eh 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/README.md +50 -33
- data/lib/eh/eh.rb +14 -16
- data/lib/eh/version.rb +1 -1
- data/spec/eh_spec.rb +0 -1
- metadata +4 -4
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -4,17 +4,25 @@ The Error handler gem provides the following major functional support for error
|
|
4
4
|
based on the ideas expressed in the Exceptional Ruby book by Avdi Grimm
|
5
5
|
|
6
6
|
o Wrapping of code blocks in exception handling logic, supporting retry, logging and exception consumption, as well as a list of handlers that can be injected
|
7
|
+
|
7
8
|
o Provision of fault tolerant logging that logs to configured logger(s), or to stderr should loggers be unavailable
|
9
|
+
|
8
10
|
o Capability to handle unhandled exceptions, log them, email them and either raise them again or convert them to system exit codes (listing of standard linux exit codes provided as constants)
|
9
11
|
|
10
12
|
The Error Handler gem allows the wrapping of arbitrary blocks of code in exception handling logic. Specifically, once an exception occurs:
|
11
13
|
|
12
14
|
o The block can be retried 'threshold' times, with a delay of 'delay' seconds in-between retries (EH::retry and EH::retry!)
|
15
|
+
|
13
16
|
o The exception can be logged to a single logger, or an array of loggers
|
17
|
+
|
14
18
|
o The exception can be re-raised (suppressed during retry, but logged, raised again after retry failure)
|
19
|
+
|
15
20
|
o The same functionality is available, with retry disabled (EH::run and EH::run!)
|
21
|
+
|
16
22
|
o The list of Linux system exit codes is also provided as EH::EX_<exit>
|
23
|
+
|
17
24
|
o Unhandled exceptions can be logged and emailed in main() using EH::report_unhandled()
|
25
|
+
|
18
26
|
o A list of handlers can be injected to do custom handling, such as email, roll-back, etc.
|
19
27
|
|
20
28
|
This gem is sponsored by Hetzner (Pty) Ltd - http://hetzner.co.za
|
@@ -35,72 +43,81 @@ Or install it yourself as:
|
|
35
43
|
|
36
44
|
## Usage
|
37
45
|
|
38
|
-
require 'rubygems'
|
39
|
-
require 'eh/eh'
|
46
|
+
require 'rubygems'
|
47
|
+
require 'eh/eh'
|
40
48
|
|
41
49
|
-- Run code block with retry, logging and exception re-raise, specifying logger, number of
|
42
50
|
times to retry, retry delay, and block arguments. Also call handle(exception, message) on
|
43
51
|
the list of handlers provided
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
52
|
+
|
53
|
+
def load_configuration(configuration_path, logger = nil)
|
54
|
+
EH::retry!(:logger => logger,
|
55
|
+
:message => "Could not parse YAML configuration",
|
56
|
+
:args => [configuration_path],
|
57
|
+
:threshold => 5,
|
58
|
+
:delay => 0.5,
|
59
|
+
:exception_filter => [RuntimeError, IOError],
|
60
|
+
:handlers => [MyEmailHandler.new, MyOtherHandler.new]) do
|
61
|
+
YAML.load(File.open(configuration_path))
|
62
|
+
end
|
63
|
+
end
|
55
64
|
|
56
65
|
-- Run code block with retry only on the exceptions listed, with the default threshold and delay
|
57
66
|
|
58
|
-
def load_configuration(configuration_path, logger = nil)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
67
|
+
def load_configuration(configuration_path, logger = nil)
|
68
|
+
EH::retry!(:args => [configuration_path], :exceptions => [IOError, RuntimeError]) do
|
69
|
+
YAML.load(File.open(configuration_path))
|
70
|
+
end
|
71
|
+
end
|
63
72
|
|
64
73
|
-- Run code block without retry, and swallowing all exceptions
|
65
74
|
|
66
|
-
def load_configuration(configuration_path, logger = nil)
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
75
|
+
def load_configuration(configuration_path, logger = nil)
|
76
|
+
EH::run(:args => [configuration_path]) do
|
77
|
+
YAML.load(File.open(configuration_path))
|
78
|
+
end
|
79
|
+
end
|
71
80
|
|
72
81
|
Any combination of the following options are allowed, both with both flavours of run() and retry().
|
73
82
|
|
74
|
-
:logger - log using the logger's error() method
|
75
|
-
:message - log this message, with the exception appended
|
76
|
-
:args - code block arguments
|
77
|
-
:threshold - the number of execution attempts
|
78
|
-
:delay - the number of seconds to delay between retries
|
79
|
-
:handlers - an array of handlers that implement handle(exception, message)
|
83
|
+
:logger - log using the logger's error() method
|
84
|
+
:message - log this message, with the exception appended
|
85
|
+
:args - code block arguments
|
86
|
+
:threshold - the number of execution attempts
|
87
|
+
:delay - the number of seconds to delay between retries
|
88
|
+
:handlers - an array of handlers that implement handle(exception, message)
|
80
89
|
|
81
90
|
Function descriptions:
|
82
91
|
|
83
92
|
run - Execute block, swallow all exceptions, no retry
|
93
|
+
|
84
94
|
run! - Execute block, re-raise exceptions, no retry
|
95
|
+
|
85
96
|
retry - Execute block, swallow all exceptions, retry
|
97
|
+
|
86
98
|
retry! - Execute block, re-raise exceptions, retry
|
87
99
|
|
88
100
|
Exception filters:
|
89
101
|
|
90
102
|
When :exception_filter is provided to retry!(), only the exceptions in the filter are retried. If retry fails, all exceptions are re-raised.
|
103
|
+
|
91
104
|
When :exception_filter is provided to retry(), only the exceptions in the filter are retried. If retry fails. Exceptions are not re-raised.
|
105
|
+
|
92
106
|
When :exception_filter is provided to run!(), only the exceptions in the filter are logged, if a logger is provided. All exceptions are re-raised.
|
107
|
+
|
93
108
|
When :exception_filter is provided to run(), only the exceptions in the filter are logged, if a logger is provided. Exceptions are not re-raised.
|
94
109
|
|
95
110
|
Unhandled exceptions can be logged and emailed as follows:
|
96
111
|
|
97
|
-
at_exit do
|
98
|
-
|
99
|
-
|
100
|
-
end
|
112
|
+
at_exit do
|
113
|
+
EH::report_unhandled(logfile = "/var/log/myapp/crash.log", email = "ernst.van.graan@hetzner.co.za")
|
114
|
+
exit EH::EX_CONFIG
|
115
|
+
end
|
101
116
|
|
102
117
|
Please send feedback and comments to the authors at:
|
118
|
+
|
103
119
|
Ernst van Graan <ernst.van.graan@hetzner.co.za>
|
120
|
+
|
104
121
|
Wynand van Dyk <wynand.van.dyk@hetzner.co.za>
|
105
122
|
|
106
123
|
## Contributing
|
data/lib/eh/eh.rb
CHANGED
@@ -16,6 +16,7 @@ module ErrorHandler
|
|
16
16
|
EX_TEMPFAIL = 75; EX_TEMPFAIL.freeze # temp failure; user is invited to retry
|
17
17
|
EX_PROTOCOL = 76; EX_PROTOCOL.freeze # remote error in protocol
|
18
18
|
EX_NOPERM = 77; EX_NOPERM.freeze # permission denied
|
19
|
+
EX_CONFIG = 78; EX_CONFIG.freeze # configuration error
|
19
20
|
|
20
21
|
ERROR = 'error'
|
21
22
|
DEBUG = 'debug'
|
@@ -23,22 +24,19 @@ module ErrorHandler
|
|
23
24
|
WARN = 'warn'
|
24
25
|
FATAL = 'fatal'
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# end
|
40
|
-
# end
|
41
|
-
#end
|
27
|
+
def self.report_unhandled(logfile = nil, handlers = nil)
|
28
|
+
if $!
|
29
|
+
message = "Unhandled exception: #{$!}"
|
30
|
+
warn message
|
31
|
+
if not logfile.nil?
|
32
|
+
open(logfile, 'a') { |f|
|
33
|
+
f.puts message
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
handle(handlers, $!, message) if not handlers.nil?
|
38
|
+
end
|
39
|
+
end
|
42
40
|
|
43
41
|
def self.retry!(options, &block)
|
44
42
|
opts = options || {}
|
data/lib/eh/version.rb
CHANGED
data/spec/eh_spec.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ernst van Graan, Wynand van Dyk
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2013-03-
|
18
|
+
date: 2013-03-14 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: bundler
|