eh 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|