kcaco 0.0.1
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/Gemfile +4 -0
- data/Gemfile.lock +28 -0
- data/README.md +123 -0
- data/Rakefile +7 -0
- data/examples/no_kcaco_different_levels.rb +24 -0
- data/examples/no_kcaco_one_line.rb +21 -0
- data/examples/simple.rb +22 -0
- data/kcaco.gemspec +20 -0
- data/lib/kcaco.rb +41 -0
- data/lib/kcaco/file_writer.rb +37 -0
- data/lib/kcaco/version.rb +7 -0
- data/lib/kcaco/wrapped_exception.rb +65 -0
- data/spec/file_writer_spec.rb +27 -0
- data/spec/kcaco_spec.rb +18 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/boom.rb +36 -0
- data/spec/wrapped_exception_spec.rb +35 -0
- metadata +129 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
kcaco (0.0.1)
|
5
|
+
guid
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.1.3)
|
11
|
+
guid (0.1.1)
|
12
|
+
rake (0.9.2.2)
|
13
|
+
rspec (2.8.0)
|
14
|
+
rspec-core (~> 2.8.0)
|
15
|
+
rspec-expectations (~> 2.8.0)
|
16
|
+
rspec-mocks (~> 2.8.0)
|
17
|
+
rspec-core (2.8.0)
|
18
|
+
rspec-expectations (2.8.0)
|
19
|
+
diff-lcs (~> 1.1.2)
|
20
|
+
rspec-mocks (2.8.0)
|
21
|
+
|
22
|
+
PLATFORMS
|
23
|
+
ruby
|
24
|
+
|
25
|
+
DEPENDENCIES
|
26
|
+
kcaco!
|
27
|
+
rake
|
28
|
+
rspec
|
data/README.md
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# Keep Calm and Carry On
|
2
|
+
|
3
|
+
## Synopsis
|
4
|
+
|
5
|
+
Ever written a long running process before? Ever had it raise
|
6
|
+
and exception and die? Ever wrapped your main loop in a
|
7
|
+
`begin..rescue` so you can just Keep Calm and Carry On? Ever found it
|
8
|
+
really annoying that logging the damn thing is so difficult?
|
9
|
+
|
10
|
+
Kcaco helps by providing some helper functions around dealing with
|
11
|
+
exceptions. Specifically with regards to logging the bastard so you
|
12
|
+
can deal with it. Example:
|
13
|
+
|
14
|
+
``` ruby
|
15
|
+
require "kcaco"
|
16
|
+
begin
|
17
|
+
raise RuntimeError.new("Goodbye, cruel world")
|
18
|
+
rescue => e
|
19
|
+
puts Kcaco.pretty(e)
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
This will print out a line like so:
|
24
|
+
`a84aedf9-8cda-13dd-123f-c8572078ea90 RuntimeError: Goodbye, cruel
|
25
|
+
world [(irb) L3]`. In case it's not obvious, the output contains a
|
26
|
+
GUID, the class of the error and the filename and linenumber it
|
27
|
+
occured on. In a single line ideal for logging. Additionally, we
|
28
|
+
serialize the exception to disk (hence the GUID - the filename we save
|
29
|
+
it too) so you can look at it later.
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
``` ruby
|
34
|
+
require "kcaco"
|
35
|
+
# in a rescue block, instead of the manual work:
|
36
|
+
logger.error Kcaco.pretty(exception)
|
37
|
+
```
|
38
|
+
|
39
|
+
This will print out a message to your logs in the format: `GUID
|
40
|
+
ExceptionClass: the message [filename.rb L123]`. Additionally, it will
|
41
|
+
write out the exception object to `Kcaco.save_path` in a file named
|
42
|
+
the same as that GUID. You can disable the save behavior with
|
43
|
+
`Kcaco.auto_save = false`.
|
44
|
+
|
45
|
+
## Example
|
46
|
+
|
47
|
+
$ bundle exec examples/simple.rb
|
48
|
+
900308c3-16ac-2803-ac97-db64464baae8 MichaelBay::Boom: ba da bloom [simple.rb L10]
|
49
|
+
|
50
|
+
cat /tmp/kcaco/exceptions/900308c3-16ac-2803-ac97-db64464baae8
|
51
|
+
time: 2012-01-06T16:01:53+02:00
|
52
|
+
type: MichaelBay::Boom
|
53
|
+
message: ba da bloom
|
54
|
+
backtrace:
|
55
|
+
examples/simple.rb:10:in `explosions'
|
56
|
+
examples/simple.rb:16
|
57
|
+
|
58
|
+
--- !ruby/exception:MichaelBay::Boom
|
59
|
+
message: ba da bloom
|
60
|
+
|
61
|
+
## Why?
|
62
|
+
|
63
|
+
Long running processes (daemons) tend to err on the side of logging
|
64
|
+
exceptions and carrying on. This is peachy, but there are some things
|
65
|
+
you definitely want to do. Without a catch-all `begin..rescue`, your
|
66
|
+
application might do this:
|
67
|
+
|
68
|
+
irb> raise RuntimeError.new("death")
|
69
|
+
RuntimeError: death
|
70
|
+
from (irb):1
|
71
|
+
|
72
|
+
That's pretty useful. Right?
|
73
|
+
|
74
|
+
In a daemon, its natural to want just as much information. Except you
|
75
|
+
will want to use a logger - especially at the appropriate level. You
|
76
|
+
may write something like this to get similar output in your logs:
|
77
|
+
|
78
|
+
``` ruby
|
79
|
+
begin
|
80
|
+
# ...
|
81
|
+
rescue => e
|
82
|
+
logger.error "#{e.class.name}: #{e.message}"
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
But now you don't know where the error came from (backtrace line #1)
|
87
|
+
or actually anything else from the backtrace. You can extend the code
|
88
|
+
with something like:
|
89
|
+
|
90
|
+
``` ruby
|
91
|
+
e.backtrace.each do |line| logger.error(line); end
|
92
|
+
```
|
93
|
+
|
94
|
+
But now you've done something horrible: if you `grep ERROR` in your
|
95
|
+
log file, the number of lines returned is no longer the number of
|
96
|
+
errors in your log. There are a bunch of ways around this:
|
97
|
+
|
98
|
+
Log the entire backtrace on 1 line, This gives you ugly logs
|
99
|
+
especially with long backtraces. For example:
|
100
|
+
|
101
|
+
$ bundle exec examples/no_kcaco_one_line.rb
|
102
|
+
E, [2012-01-06T16:26:27.705513 #647] ERROR -- : MichaelBay::Boom: ba da bloom ["examples/no_kcaco_one_line.rb:10:in `explosions'", "examples/no_kcaco_one_line.rb:17"]
|
103
|
+
|
104
|
+
Log the backtrace at a different level, e.g. `DEBUG`. This means you
|
105
|
+
have to run with verbose logging:
|
106
|
+
|
107
|
+
$ bundle exec examples/no_kcaco_different_levels.rb
|
108
|
+
E, [2012-01-06T16:28:33.903684 #736] ERROR -- : MichaelBay::Boom: ba da bloom
|
109
|
+
D, [2012-01-06T16:28:33.903784 #736] DEBUG -- : examples/no_kcaco_different_levels.rb:10:in `explosions'
|
110
|
+
D, [2012-01-06T16:28:33.903814 #736] DEBUG -- : examples/no_kcaco_different_levels.rb:17
|
111
|
+
|
112
|
+
Or you can roll your own smarts. Repeatedly. Or just use some like Kcaco. Quite simply what it does is:
|
113
|
+
|
114
|
+
* Save you having to format the log message by doing it for you.
|
115
|
+
* Write more detail to a separate file where you can inspect it later.
|
116
|
+
|
117
|
+
.. and you get
|
118
|
+
|
119
|
+
bundle exec examples/simple.rb
|
120
|
+
E, [2012-01-06T16:29:50.730922 #793] ERROR -- : ae58d80f-4bc3-899a-fd0b-2c831833510c MichaelBay::Boom: ba da bloom [simple.rb L11]
|
121
|
+
|
122
|
+
In this example, you could see the saved exception
|
123
|
+
`ae58d80f-4bc3-899a-fd0b-2c831833510c` on disk to get the full backtrace.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
class MichaelBay
|
6
|
+
|
7
|
+
class Boom < RuntimeError; end
|
8
|
+
|
9
|
+
def explosions
|
10
|
+
raise Boom.new("ba da bloom")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
if __FILE__ == $0
|
15
|
+
logger = Logger.new(STDOUT)
|
16
|
+
begin
|
17
|
+
MichaelBay.new.explosions
|
18
|
+
rescue => e
|
19
|
+
logger.error "#{e.class.name}: #{e.message}"
|
20
|
+
e.backtrace.each do |line|
|
21
|
+
logger.debug line
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
class MichaelBay
|
6
|
+
|
7
|
+
class Boom < RuntimeError; end
|
8
|
+
|
9
|
+
def explosions
|
10
|
+
raise Boom.new("ba da bloom")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
if __FILE__ == $0
|
15
|
+
logger = Logger.new(STDOUT)
|
16
|
+
begin
|
17
|
+
MichaelBay.new.explosions
|
18
|
+
rescue => e
|
19
|
+
logger.error "#{e.class.name}: #{e.message} #{e.backtrace.inspect}"
|
20
|
+
end
|
21
|
+
end
|
data/examples/simple.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
require "kcaco"
|
5
|
+
|
6
|
+
class MichaelBay
|
7
|
+
|
8
|
+
class Boom < RuntimeError; end
|
9
|
+
|
10
|
+
def explosions
|
11
|
+
raise Boom.new("ba da bloom")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if __FILE__ == $0
|
16
|
+
logger = Logger.new(STDOUT)
|
17
|
+
begin
|
18
|
+
MichaelBay.new.explosions
|
19
|
+
rescue => e
|
20
|
+
logger.error Kcaco.pretty(e)
|
21
|
+
end
|
22
|
+
end
|
data/kcaco.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/kcaco/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Marc Bowes"]
|
6
|
+
gem.email = ["marcbowes@gmail.com"]
|
7
|
+
gem.description = %q{Helpers for dealing with exceptions}
|
8
|
+
gem.summary = %q{Bored of writing out exceptions to logs?}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = Dir["**/*"]
|
12
|
+
gem.test_files = Dir["spec/**/*"]
|
13
|
+
gem.name = "kcaco"
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
gem.version = Kcaco.version
|
16
|
+
|
17
|
+
gem.add_runtime_dependency("guid")
|
18
|
+
gem.add_development_dependency("rake")
|
19
|
+
gem.add_development_dependency("rspec")
|
20
|
+
end
|
data/lib/kcaco.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "kcaco/version"
|
2
|
+
require "kcaco/wrapped_exception"
|
3
|
+
require "kcaco/file_writer"
|
4
|
+
|
5
|
+
module Kcaco
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def auto_save=(bool)
|
10
|
+
@auto_save = bool
|
11
|
+
end
|
12
|
+
|
13
|
+
def auto_save?
|
14
|
+
@auto_save != false
|
15
|
+
end
|
16
|
+
|
17
|
+
def save_path=(path)
|
18
|
+
@save_path = path
|
19
|
+
end
|
20
|
+
|
21
|
+
def save_path(wrapped_exception = nil)
|
22
|
+
@save_path ||= "/tmp/kcaco/exceptions"
|
23
|
+
if wrapped_exception
|
24
|
+
File.join(@save_path, wrapped_exception.uuid)
|
25
|
+
else
|
26
|
+
@save_path
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def save(wrapped_exception)
|
31
|
+
Kcaco::FileWriter.new(wrapped_exception).
|
32
|
+
save(save_path(wrapped_exception))
|
33
|
+
end
|
34
|
+
|
35
|
+
def pretty(exception)
|
36
|
+
wrapped_exception = Kcaco::WrappedException.new(exception)
|
37
|
+
save(wrapped_exception) if auto_save?
|
38
|
+
wrapped_exception.pretty
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Kcaco
|
2
|
+
class FileWriter
|
3
|
+
|
4
|
+
require "time"
|
5
|
+
require "fileutils"
|
6
|
+
require "yaml"
|
7
|
+
|
8
|
+
|
9
|
+
attr_accessor :exception
|
10
|
+
|
11
|
+
def initialize(exception)
|
12
|
+
self.exception = exception
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def save(path)
|
17
|
+
FileUtils.mkdir_p(File.dirname(path))
|
18
|
+
File.open(path, "w") do |f|
|
19
|
+
[
|
20
|
+
["time", Time.now.iso8601],
|
21
|
+
["type", exception.type],
|
22
|
+
["message", exception.message],
|
23
|
+
].each do |label, text|
|
24
|
+
f.puts([label, text].join(": "))
|
25
|
+
end
|
26
|
+
|
27
|
+
f.puts("backtrace:")
|
28
|
+
exception.backtrace.each do |line|
|
29
|
+
f.puts(line)
|
30
|
+
end
|
31
|
+
|
32
|
+
f.puts
|
33
|
+
f.puts(exception.to_yaml)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Kcaco
|
2
|
+
class WrappedException
|
3
|
+
|
4
|
+
require "guid"
|
5
|
+
|
6
|
+
|
7
|
+
attr_accessor :exception
|
8
|
+
|
9
|
+
def initialize(exception)
|
10
|
+
self.exception = exception
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def type
|
15
|
+
exception.class.name
|
16
|
+
end
|
17
|
+
|
18
|
+
def message
|
19
|
+
exception.message
|
20
|
+
end
|
21
|
+
|
22
|
+
def backtrace
|
23
|
+
exception.backtrace
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_yaml
|
27
|
+
exception.to_yaml
|
28
|
+
end
|
29
|
+
|
30
|
+
def extract_filename_and_line_no(line)
|
31
|
+
if (m = line.match(/(.+):(\d+):/))
|
32
|
+
[File.basename(m[1]), m[2].to_i]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def filename_and_line_no
|
37
|
+
@filename_and_line_no ||=
|
38
|
+
extract_filename_and_line_no(backtrace.first)
|
39
|
+
end
|
40
|
+
|
41
|
+
def filename
|
42
|
+
filename_and_line_no.first
|
43
|
+
end
|
44
|
+
|
45
|
+
def line_no
|
46
|
+
filename_and_line_no.last
|
47
|
+
end
|
48
|
+
|
49
|
+
def title
|
50
|
+
[type, message].join(": ")
|
51
|
+
end
|
52
|
+
|
53
|
+
def pretty
|
54
|
+
[
|
55
|
+
uuid,
|
56
|
+
title,
|
57
|
+
"[%s L%i]" % [filename, line_no],
|
58
|
+
].join(" ")
|
59
|
+
end
|
60
|
+
|
61
|
+
def uuid
|
62
|
+
@uuid ||= Guid.new.to_s
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
require "kcaco/wrapped_exception"
|
5
|
+
require "kcaco/file_writer"
|
6
|
+
|
7
|
+
module Kcaco
|
8
|
+
describe Exception do
|
9
|
+
|
10
|
+
let(:boom) { Boom.new }
|
11
|
+
let(:wrapped_exception) { WrappedException.new(boom.rescued) }
|
12
|
+
let(:fw) { FileWriter.new(wrapped_exception) }
|
13
|
+
|
14
|
+
|
15
|
+
it "should save the exception" do
|
16
|
+
path = File.join("/tmp", [File.basename(__FILE__), Process.pid.to_s].join("-"))
|
17
|
+
begin
|
18
|
+
fw.save(path)
|
19
|
+
ensure
|
20
|
+
FileUtils.rm(path)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Kind of difficult to test the content of this file because of
|
24
|
+
# times and paths.
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/kcaco_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "kcaco"
|
4
|
+
|
5
|
+
describe Kcaco do
|
6
|
+
|
7
|
+
let(:boom) { Boom.new }
|
8
|
+
|
9
|
+
before do
|
10
|
+
Kcaco.auto_save = false
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should create a pretty log entry" do
|
14
|
+
exception = boom.rescued
|
15
|
+
rest = Regexp.escape("RuntimeError: exception [boom.rb L10]")
|
16
|
+
Kcaco.pretty(exception).should =~ /[a-z0-9\-]+ #{rest}/
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "support/boom"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Boom
|
2
|
+
|
3
|
+
DEFAULT_MESSAGE = "exception"
|
4
|
+
|
5
|
+
def create(message = DEFAULT_MESSAGE)
|
6
|
+
RuntimeError.new(message)
|
7
|
+
end
|
8
|
+
|
9
|
+
def raise(message = DEFAULT_MESSAGE)
|
10
|
+
Kernel.raise(create(message))
|
11
|
+
end
|
12
|
+
|
13
|
+
def rescued(message = DEFAULT_MESSAGE)
|
14
|
+
begin
|
15
|
+
self.raise
|
16
|
+
rescue RuntimeError => e
|
17
|
+
e
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
|
23
|
+
def raise_line_no
|
24
|
+
@raise_line_no ||= get_raise_line_no
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_raise_line_no
|
28
|
+
File.open(__FILE__, "r") do |f|
|
29
|
+
f.each do |line|
|
30
|
+
return f.lineno if line.include?("Kernel.raise")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "kcaco/wrapped_exception"
|
4
|
+
|
5
|
+
module Kcaco
|
6
|
+
describe WrappedException do
|
7
|
+
|
8
|
+
let(:boom) { Boom.new }
|
9
|
+
let(:we) { WrappedException.new(boom.rescued) }
|
10
|
+
|
11
|
+
|
12
|
+
it "should generate an we title" do
|
13
|
+
we.title.should == "RuntimeError: exception"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should figure out the file name that caused the we" do
|
17
|
+
we.filename.should == "boom.rb"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should figure out the line number that caused the we" do
|
21
|
+
we.line_no.should == Boom.raise_line_no
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should create a pretty version" do
|
25
|
+
we.should_receive(:uuid).and_return("uuid")
|
26
|
+
we.pretty.should == "uuid RuntimeError: exception [boom.rb L10]"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should make a uuid" do
|
30
|
+
uuid = we.uuid
|
31
|
+
we.uuid.should =~ /[a-z0-9\-]+/
|
32
|
+
we.uuid.should == uuid
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kcaco
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Marc Bowes
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-01-06 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
type: :runtime
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
name: guid
|
33
|
+
version_requirements: *id001
|
34
|
+
prerelease: false
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
type: :development
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
name: rake
|
47
|
+
version_requirements: *id002
|
48
|
+
prerelease: false
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
type: :development
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
name: rspec
|
61
|
+
version_requirements: *id003
|
62
|
+
prerelease: false
|
63
|
+
description: Helpers for dealing with exceptions
|
64
|
+
email:
|
65
|
+
- marcbowes@gmail.com
|
66
|
+
executables: []
|
67
|
+
|
68
|
+
extensions: []
|
69
|
+
|
70
|
+
extra_rdoc_files: []
|
71
|
+
|
72
|
+
files:
|
73
|
+
- examples/no_kcaco_different_levels.rb
|
74
|
+
- examples/simple.rb
|
75
|
+
- examples/no_kcaco_one_line.rb
|
76
|
+
- Rakefile
|
77
|
+
- README.md
|
78
|
+
- Gemfile
|
79
|
+
- kcaco.gemspec
|
80
|
+
- spec/support/boom.rb
|
81
|
+
- spec/wrapped_exception_spec.rb
|
82
|
+
- spec/spec_helper.rb
|
83
|
+
- spec/kcaco_spec.rb
|
84
|
+
- spec/file_writer_spec.rb
|
85
|
+
- Gemfile.lock
|
86
|
+
- lib/kcaco.rb
|
87
|
+
- lib/kcaco/file_writer.rb
|
88
|
+
- lib/kcaco/wrapped_exception.rb
|
89
|
+
- lib/kcaco/version.rb
|
90
|
+
has_rdoc: true
|
91
|
+
homepage: ""
|
92
|
+
licenses: []
|
93
|
+
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 3
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
version: "0"
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
hash: 3
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
requirements: []
|
118
|
+
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 1.6.2
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Bored of writing out exceptions to logs?
|
124
|
+
test_files:
|
125
|
+
- spec/support/boom.rb
|
126
|
+
- spec/wrapped_exception_spec.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- spec/kcaco_spec.rb
|
129
|
+
- spec/file_writer_spec.rb
|