summaryrefslogtreecommitdiffstats
path: root/lib/puppet/util/errors.rb
blob: 3aa65d06c76170415834ea5f34dfb0ad6df7abf8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# Some helper methods for throwing errors.
module Puppet::Util::Errors
    # Throw a dev error.
    def devfail(msg)
        self.fail(Puppet::DevError, msg)
    end

    # Add line and file info if available and appropriate.
    def adderrorcontext(error, other = nil)
        error.line ||= self.line if self.respond_to?(:line) and self.line
        error.file ||= self.file if self.respond_to?(:file) and self.file

        error.set_backtrace other.backtrace if other and other.respond_to?(:backtrace)

        return error
    end

    def error_context
        if file and line
            " at #{file}:#{line}"
        elsif line
            " at line #{line}"
        elsif file
            " in #{file}"
        else
            ""
        end
    end

    # Wrap a call in such a way that we always throw the right exception and keep
    # as much context as possible.
    def exceptwrap(options = {})
        options[:type] ||= Puppet::DevError
        begin
            return yield
        rescue Puppet::Error => detail
            raise adderrorcontext(detail)
        rescue => detail
            message = options[:message] || "#{self.class} failed with error #{detail.class}: #{detail}"

            error = options[:type].new(message)
            # We can't use self.fail here because it always expects strings,
            # not exceptions.
            raise adderrorcontext(error, detail)
        end

        return retval
    end

    # Throw an error, defaulting to a Puppet::Error.
    def fail(*args)
        if args[0].is_a?(Class)
            type = args.shift
        else
            type = Puppet::Error
        end

        error = adderrorcontext(type.new(args.join(" ")))

        raise error
    end
end