open_exception 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +44 -0
- data/VERSION +1 -1
- data/lib/open_exception.rb +5 -0
- data/lib/open_exception/growl_support.rb +13 -5
- data/lib/open_exception/open_exception.rb +41 -24
- data/lib/open_exception/rails.rb +1 -1
- data/open_exception.gemspec +4 -8
- data/spec/open_exception_spec.rb +6 -6
- metadata +5 -8
- data/README.rdoc +0 -17
- data/init.rb +0 -1
- data/rails/init.rb +0 -1
- data/test_data/raiser.rb +0 -25
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
open_exception
|
2
|
+
==============
|
3
|
+
|
4
|
+
open_exception opens an exception in your favorite editor when developing locally. It
|
5
|
+
works by parsing the backtrace, and opening the offending file at the offending line
|
6
|
+
in your favorite editor (assuming your favorite editor supports remote open commands).
|
7
|
+
|
8
|
+
You can add filters that allow you to ignore some exceptions, and filters that allow you
|
9
|
+
to scope the backtrace search. The backtrace scoping is useful for opening the last call
|
10
|
+
in your application code when the exception occurs in a framework or lib.
|
11
|
+
|
12
|
+
If you are on MacOSX and have the [growl gem](http://rubygems.org/gems/growl) installed,
|
13
|
+
you will get a growl notification with the exception message when the file is opened.
|
14
|
+
|
15
|
+
Configuration
|
16
|
+
-------------
|
17
|
+
|
18
|
+
To configure, pass a block to the configure method:
|
19
|
+
|
20
|
+
OpenException.configure do |oe|
|
21
|
+
oe.open_with = :emacs
|
22
|
+
end
|
23
|
+
|
24
|
+
Rails Integration
|
25
|
+
-----------------
|
26
|
+
|
27
|
+
auto filter
|
28
|
+
|
29
|
+
Standalone/Other Frameworks
|
30
|
+
---------------------------
|
31
|
+
|
32
|
+
|
33
|
+
Note on Patches/Pull Requests
|
34
|
+
-----------------------------
|
35
|
+
|
36
|
+
* Fork the project.
|
37
|
+
* Make your feature addition or bug fix.
|
38
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
39
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
40
|
+
* Send me a pull request. Bonus points for topic branches.
|
41
|
+
|
42
|
+
== Copyright
|
43
|
+
|
44
|
+
Copyright (c) 2010 Tobias Crawley. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.1
|
data/lib/open_exception.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/open_exception/open_exception"
|
2
2
|
require File.dirname(__FILE__) + "/open_exception/rails" if defined?(ActionController)
|
3
3
|
|
4
|
+
init_message = "** open_extension initialized "
|
5
|
+
|
4
6
|
begin
|
5
7
|
require 'growl'
|
6
8
|
require File.dirname(__FILE__) + "/open_exception/growl_support"
|
9
|
+
init_message << "with growl support"
|
7
10
|
rescue LoadError
|
8
11
|
#ignore
|
9
12
|
end
|
13
|
+
|
14
|
+
puts init_message
|
@@ -1,9 +1,17 @@
|
|
1
1
|
module OpenException
|
2
2
|
module GrowlSupport
|
3
|
+
def self.included(base)
|
4
|
+
if !base.instance_methods.include?(:open_without_growl)
|
5
|
+
base.send(:alias_method, :open_file_without_growl, :open_file)
|
6
|
+
base.send(:alias_method, :open_file, :open_file_with_growl)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
3
10
|
protected
|
4
|
-
def
|
5
|
-
|
6
|
-
|
11
|
+
def open_file_with_growl(file, line)
|
12
|
+
puts 'growl open file'
|
13
|
+
growl_notify(file, line) if File.readable?(file)
|
14
|
+
open_file_without_growl(file, line)
|
7
15
|
end
|
8
16
|
|
9
17
|
def growl_notify(file, line)
|
@@ -16,10 +24,10 @@ module OpenException
|
|
16
24
|
end
|
17
25
|
|
18
26
|
def growl_message(file, line)
|
19
|
-
msg = "
|
27
|
+
msg = "Exception: #{exception.message} at #{exception.backtrace.first}\nOpening #{file}:#{line}"
|
20
28
|
msg << " in #{options[:open_with]}" if options[:open_with].is_a?(Symbol)
|
21
29
|
end
|
22
30
|
end
|
23
31
|
end
|
24
32
|
|
25
|
-
OpenException::ExceptionOpener.send(:include, OpenException::GrowlSupport)
|
33
|
+
OpenException::ExceptionOpener.send(:include, OpenException::GrowlSupport)
|
@@ -1,10 +1,24 @@
|
|
1
1
|
module OpenException
|
2
|
+
|
3
|
+
EDITOR_COMMANDS = {
|
4
|
+
:emacs => '/usr/bin/emacsclient -n +{line} {file}',
|
5
|
+
:textmate => '/usr/local/bin/mate -a -d -l {line} {file}',
|
6
|
+
:macvim => '/usr/local/bin/mvim +{line} {file}'
|
7
|
+
}
|
2
8
|
|
9
|
+
DEFAULT_OPTIONS = {
|
10
|
+
:open_with => :emacs,
|
11
|
+
:exclusion_filters => [], #[ExceptionClass, lambda] # any can return/be true to exclude
|
12
|
+
:backtrace_line_filters => [] #[/regex/, lambda] # the first backtrace line that returns true is used
|
13
|
+
}
|
14
|
+
|
3
15
|
class << self
|
4
|
-
attr_writer :options
|
5
|
-
|
6
16
|
def options
|
7
|
-
@options ||=
|
17
|
+
@options ||= DEFAULT_OPTIONS.clone
|
18
|
+
end
|
19
|
+
|
20
|
+
def configure
|
21
|
+
yield Configurator.new(options)
|
8
22
|
end
|
9
23
|
|
10
24
|
def open(exception, options = { })
|
@@ -13,22 +27,12 @@ module OpenException
|
|
13
27
|
end
|
14
28
|
|
15
29
|
class ExceptionOpener
|
16
|
-
DEFAULT_OPTIONS = {
|
17
|
-
:open_with => :emacs,
|
18
|
-
:emacs_command => '/usr/bin/emacsclient -n +{line} {file}',
|
19
|
-
:textmate_command => '/usr/local/bin/mate -a -d -l {line} {file}',
|
20
|
-
:macvim_command => '/usr/local/bin/mvim +{line} {file}'
|
21
|
-
# :exclusion_filter => [ExceptionClass, lambda] # any can return/be
|
22
|
-
# true to exclude
|
23
|
-
# :backtrace_line_filter => [/regex/, lambda] # the first backtrace
|
24
|
-
# line that returns true is used
|
25
|
-
}
|
26
30
|
|
27
31
|
attr_accessor :options
|
28
32
|
|
29
33
|
def initialize(exception, options = {})
|
30
34
|
@exception = exception
|
31
|
-
@options =
|
35
|
+
@options = OpenException.options.merge(options)
|
32
36
|
end
|
33
37
|
|
34
38
|
def open
|
@@ -37,21 +41,21 @@ module OpenException
|
|
37
41
|
open_file(*file_and_line) if file_and_line
|
38
42
|
end
|
39
43
|
end
|
40
|
-
|
44
|
+
|
41
45
|
protected
|
42
46
|
attr_reader :exception
|
43
|
-
|
47
|
+
|
44
48
|
def extract_file_and_line
|
45
49
|
if exception.backtrace and
|
46
|
-
|
50
|
+
filter_backtrace(exception.backtrace) =~ /(.*?):(\d*)/
|
47
51
|
[$1, $2]
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
51
55
|
def filter_backtrace(backtrace)
|
52
|
-
if options[:
|
56
|
+
if !options[:backtrace_line_filters].empty?
|
53
57
|
backtrace.find do |line|
|
54
|
-
apply_backtrace_filter(options[:
|
58
|
+
apply_backtrace_filter(options[:backtrace_line_filters], line)
|
55
59
|
end
|
56
60
|
else
|
57
61
|
backtrace.first
|
@@ -67,10 +71,10 @@ module OpenException
|
|
67
71
|
line =~ filter
|
68
72
|
end
|
69
73
|
end
|
70
|
-
|
74
|
+
|
71
75
|
def exclude_exception?
|
72
|
-
if options[:
|
73
|
-
apply_exclusion_filter(options[:
|
76
|
+
if !options[:exclusion_filters].empty?
|
77
|
+
apply_exclusion_filter(options[:exclusion_filters])
|
74
78
|
end
|
75
79
|
end
|
76
80
|
|
@@ -83,7 +87,7 @@ module OpenException
|
|
83
87
|
exception.is_a?(filter)
|
84
88
|
end
|
85
89
|
end
|
86
|
-
|
90
|
+
|
87
91
|
def open_file(file_name, line_number)
|
88
92
|
if File.readable?(file_name)
|
89
93
|
cmd = open_command.gsub('{file}', file_name).gsub('{line}', line_number)
|
@@ -94,11 +98,24 @@ module OpenException
|
|
94
98
|
|
95
99
|
def open_command
|
96
100
|
if options[:open_with].is_a?(Symbol)
|
97
|
-
|
101
|
+
EDITOR_COMMANDS[options[:open_with]]
|
98
102
|
else
|
99
103
|
options[:open_with]
|
100
104
|
end
|
101
105
|
end
|
102
106
|
end
|
107
|
+
|
108
|
+
class Configurator
|
109
|
+
def initialize(options)
|
110
|
+
@options = options
|
111
|
+
end
|
103
112
|
|
113
|
+
def method_missing(method, arg = nil)
|
114
|
+
if method.to_s =~ /(.*?)=/
|
115
|
+
@options[$1.to_sym] = arg
|
116
|
+
else
|
117
|
+
@options[method]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
104
121
|
end
|
data/lib/open_exception/rails.rb
CHANGED
@@ -18,5 +18,5 @@ end
|
|
18
18
|
|
19
19
|
if !ActionController::Base.ancestors.include?(OpenException::ActionControllerExtensions)
|
20
20
|
ActionController::Base.send(:include, OpenException::ActionControllerExtensions)
|
21
|
-
OpenException.options[:
|
21
|
+
OpenException.options[:backtrace_line_filters] << %r{#{Rails.root}/(app|lib)}
|
22
22
|
end
|
data/open_exception.gemspec
CHANGED
@@ -5,35 +5,31 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{open_exception}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Tobias Crawley"]
|
12
|
-
s.date = %q{2010-04-
|
12
|
+
s.date = %q{2010-04-26}
|
13
13
|
s.description = %q{}
|
14
14
|
s.email = %q{tcrawley@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
"README.
|
17
|
+
"README.md"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".gitignore",
|
22
22
|
"LICENSE",
|
23
|
-
"README.rdoc",
|
24
23
|
"Rakefile",
|
25
24
|
"VERSION",
|
26
|
-
"init.rb",
|
27
25
|
"lib/open_exception.rb",
|
28
26
|
"lib/open_exception/growl_support.rb",
|
29
27
|
"lib/open_exception/open_exception.rb",
|
30
28
|
"lib/open_exception/rails.rb",
|
31
29
|
"open_exception.gemspec",
|
32
|
-
"rails/init.rb",
|
33
30
|
"spec/open_exception_spec.rb",
|
34
31
|
"spec/spec.opts",
|
35
|
-
"spec/spec_helper.rb"
|
36
|
-
"test_data/raiser.rb"
|
32
|
+
"spec/spec_helper.rb"
|
37
33
|
]
|
38
34
|
s.homepage = %q{http://github.com/tobias/open_exception}
|
39
35
|
s.rdoc_options = ["--charset=UTF-8"]
|
data/spec/open_exception_spec.rb
CHANGED
@@ -9,19 +9,19 @@ describe "OpenException" do
|
|
9
9
|
|
10
10
|
it "should filter with a regex" do
|
11
11
|
@opener = opener(stub_exception,
|
12
|
-
:
|
12
|
+
:backtrace_line_filters => [/other_file/])
|
13
13
|
@opener.send(:extract_file_and_line).should == ["/some/other_file.rb", '22']
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should filter with a lambda" do
|
17
17
|
@opener = opener(stub_exception,
|
18
|
-
:
|
18
|
+
:backtrace_line_filters => [lambda { |line| line =~ /other_file/ }])
|
19
19
|
@opener.send(:extract_file_and_line).should == ["/some/other_file.rb", '22']
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should filter with an array of filters" do
|
23
23
|
@opener = opener(stub_exception,
|
24
|
-
:
|
24
|
+
:backtrace_line_filters => [/not gonna match/,
|
25
25
|
/other_file/])
|
26
26
|
@opener.send(:extract_file_and_line).should == ["/some/other_file.rb", '22']
|
27
27
|
end
|
@@ -50,19 +50,19 @@ describe "OpenException" do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it "should exclude based on exception class" do
|
53
|
-
@opener = opener(Exception.new, :
|
53
|
+
@opener = opener(Exception.new, :exclusion_filters => [Exception])
|
54
54
|
@opener.should_not_receive(:extract_file_and_line)
|
55
55
|
@opener.open
|
56
56
|
end
|
57
57
|
|
58
58
|
it "should exclude based on a lambda" do
|
59
|
-
@opener = opener(Exception.new, :
|
59
|
+
@opener = opener(Exception.new, :exclusion_filters => [lambda { |ex| true }])
|
60
60
|
@opener.should_not_receive(:extract_file_and_line)
|
61
61
|
@opener.open
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should exclude based on an array of filters" do
|
65
|
-
@opener = opener(Exception.new, :
|
65
|
+
@opener = opener(Exception.new, :exclusion_filters => [StandardError, Exception])
|
66
66
|
@opener.should_not_receive(:extract_file_and_line)
|
67
67
|
@opener.open
|
68
68
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 1
|
9
|
+
version: 0.2.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Tobias Crawley
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-26 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -39,25 +39,22 @@ extensions: []
|
|
39
39
|
|
40
40
|
extra_rdoc_files:
|
41
41
|
- LICENSE
|
42
|
-
- README.
|
42
|
+
- README.md
|
43
43
|
files:
|
44
44
|
- .document
|
45
45
|
- .gitignore
|
46
46
|
- LICENSE
|
47
|
-
- README.rdoc
|
48
47
|
- Rakefile
|
49
48
|
- VERSION
|
50
|
-
- init.rb
|
51
49
|
- lib/open_exception.rb
|
52
50
|
- lib/open_exception/growl_support.rb
|
53
51
|
- lib/open_exception/open_exception.rb
|
54
52
|
- lib/open_exception/rails.rb
|
55
53
|
- open_exception.gemspec
|
56
|
-
- rails/init.rb
|
57
54
|
- spec/open_exception_spec.rb
|
58
55
|
- spec/spec.opts
|
59
56
|
- spec/spec_helper.rb
|
60
|
-
-
|
57
|
+
- README.md
|
61
58
|
has_rdoc: true
|
62
59
|
homepage: http://github.com/tobias/open_exception
|
63
60
|
licenses: []
|
data/README.rdoc
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
= open_exception
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Note on Patches/Pull Requests
|
6
|
-
|
7
|
-
* Fork the project.
|
8
|
-
* Make your feature addition or bug fix.
|
9
|
-
* Add tests for it. This is important so I don't break it in a
|
10
|
-
future version unintentionally.
|
11
|
-
* Commit, do not mess with rakefile, version, or history.
|
12
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
-
* Send me a pull request. Bonus points for topic branches.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2010 Tobias Crawley. See LICENSE for details.
|
data/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "lib", "open_exception")
|
data/rails/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "..", "init")
|
data/test_data/raiser.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../lib/open_exception')
|
2
|
-
|
3
|
-
class Raiser
|
4
|
-
def raise_now
|
5
|
-
raise Exception.new
|
6
|
-
end
|
7
|
-
|
8
|
-
def raise_first_level
|
9
|
-
raise_now
|
10
|
-
end
|
11
|
-
|
12
|
-
def raise_second_level
|
13
|
-
raise_first_level
|
14
|
-
end
|
15
|
-
|
16
|
-
def file
|
17
|
-
__FILE__
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.raise_and_open(options = {})
|
21
|
-
Raiser.new.raise_now
|
22
|
-
rescue Exception
|
23
|
-
OpenException.open($!, options)
|
24
|
-
end
|
25
|
-
end
|