cgi-exception 0.2.0 → 0.3.0
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/CHANGES.txt +12 -0
- data/README.txt +55 -16
- data/cgi-exception.gemspec +46 -0
- data/lib/cgi_exception.rb +78 -52
- data/test/test_cgi_exception.rb +4 -4
- metadata +5 -4
data/CHANGES.txt
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
= CHANGES
|
2
2
|
|
3
3
|
|
4
|
+
== Release 0.3.0 (2008-07-19)
|
5
|
+
|
6
|
+
=== Enhancements
|
7
|
+
|
8
|
+
* Re-writed entirely
|
9
|
+
|
10
|
+
* EditorKicker support to invoke TextMate or Emacs automatically
|
11
|
+
when an error raised.
|
12
|
+
|
13
|
+
* Add example script for FastCGI
|
14
|
+
|
15
|
+
|
4
16
|
|
5
17
|
== Release 0.2.0 (2008-02-21)
|
6
18
|
|
data/README.txt
CHANGED
@@ -1,20 +1,24 @@
|
|
1
1
|
= README.txt
|
2
2
|
|
3
|
-
Release: 0.
|
4
|
-
|
5
|
-
copyright(c) 2007-2008 kuwata-lab.com all rights reserved.
|
3
|
+
Release: 0.3.0
|
6
4
|
|
5
|
+
http://cgi-exception.rubyforge.org/
|
7
6
|
http://rubyforge.org/projects/cgi-exception/
|
8
7
|
|
9
8
|
|
10
9
|
== About
|
11
10
|
|
12
|
-
|
11
|
+
CGI-Exception is a small script to show exception raised in your
|
13
12
|
CGI script into browser, like PHP. You don't need to look for error
|
14
13
|
messages in Web server's log file.
|
15
14
|
|
16
|
-
|
17
|
-
|
15
|
+
In addition, CGI-Exception supports EditorKicker which is a pretty
|
16
|
+
tool to invoke your favorite editor and open errored file when an
|
17
|
+
exception raised on your script.
|
18
|
+
See http://editorkicker.rubyforge.org/ for details.
|
19
|
+
|
20
|
+
NOTICE: CGI-Exception supports CGI and mod_ruby, and it is easy
|
21
|
+
to use it in FastCGI (see blow for detail).
|
18
22
|
|
19
23
|
|
20
24
|
== Install
|
@@ -27,8 +31,10 @@ Or, just type 'ruby setup.rb' with administrator priviledge.
|
|
27
31
|
Or, copy 'lib/cgi_exception.rb' to proper directory such as
|
28
32
|
'/usr/local/lib/ruby/site_ruby/1.8'.
|
29
33
|
|
34
|
+
It is recommended to install EditorKicker as well as CGI-Exception.
|
35
|
+
|
30
36
|
NOTICE: It is NOT recommended to install by RubyGems, because
|
31
|
-
'require "rubygems"' is too heavy for CGI program.
|
37
|
+
'require "rubygems"' is too heavy operation for CGI program.
|
32
38
|
|
33
39
|
|
34
40
|
== Usage
|
@@ -37,25 +43,56 @@ All you have to do is to require 'cgi_exception'.
|
|
37
43
|
If you do so and exception raised, what and where exception raised will
|
38
44
|
be shown in browser.
|
39
45
|
|
46
|
+
In addition, if you installed and required EditorKicker, TextMate or
|
47
|
+
Emacs will be invoked automatically when you got exceptions.
|
48
|
+
See README of EditorKicker for details.
|
49
|
+
|
40
50
|
|
41
51
|
== Example
|
42
52
|
|
43
|
-
For example, the following code will raise exception at line
|
53
|
+
For example, the following code will raise exception at line 5, because
|
44
54
|
local variable 'user' is not initialized.
|
45
55
|
|
46
|
-
#!/usr/bin/env ruby
|
47
|
-
require 'cgi'
|
48
|
-
require 'cgi_exception'
|
49
|
-
|
50
|
-
print CGI.new.header
|
51
|
-
print
|
56
|
+
1: #!/usr/bin/env ruby
|
57
|
+
2: require 'cgi'
|
58
|
+
3: require 'cgi_exception'
|
59
|
+
4: require 'editor_kicker' if ENV['SERVER_NAME'] == 'localhost'
|
60
|
+
5: print CGI.new.header('text/html')
|
61
|
+
6: print " <h1>Example</h1>\n"
|
62
|
+
7: print " <p>Hello #{user}</p>\n" # ERROR!
|
63
|
+
8: print " <p>unreachable</p>\n"
|
52
64
|
|
53
65
|
You'll see the following message in your browser if you access the above
|
54
66
|
CGI script.
|
55
67
|
|
56
|
-
/var/www/cgi-bin/foo.cgi:
|
68
|
+
/var/www/cgi-bin/foo.cgi:7: undefined local variable or method `user'
|
57
69
|
for main:Object (NameError)
|
58
70
|
|
71
|
+
If you are using FastCGI, try the following code:
|
72
|
+
|
73
|
+
#!/usr/bin/env ruby
|
74
|
+
require 'cgi'
|
75
|
+
require 'fcgi'
|
76
|
+
require 'cgi_exception'
|
77
|
+
|
78
|
+
FCGI.each do |cgi|
|
79
|
+
begin
|
80
|
+
print cgi.header('text/html')
|
81
|
+
print " <h1>Example</h1>\n"
|
82
|
+
print " <p>Hello #{user}</p>\n" # ERROR!
|
83
|
+
print " <p>unreachable</p>\n"
|
84
|
+
rescue Exception => ex
|
85
|
+
CGIExceptionPrinter.new(false).handle(ex)
|
86
|
+
## invoke Emacs automatically only when on localhost
|
87
|
+
if cgi.env_table['SERVER_NAME'] == 'localhost'
|
88
|
+
require 'editor_kicker'
|
89
|
+
ENV['EDITOR_KICKER'] = \
|
90
|
+
"emacsclient -n -s /tmp/emacs501/server +%s '%s'"
|
91
|
+
EditorKicker.handle(ex)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
59
96
|
|
60
97
|
== License
|
61
98
|
|
@@ -64,4 +101,6 @@ public domain
|
|
64
101
|
|
65
102
|
== Author
|
66
103
|
|
67
|
-
makoto kuwata <kwa
|
104
|
+
makoto kuwata <kwa(at)kuwata-lab.com>
|
105
|
+
|
106
|
+
copyright(c) 2007-2008 kuwata-lab.com all rights reserved.
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
###
|
4
|
+
### $Rev: 17 $
|
5
|
+
### $Release: 0.3.0 $
|
6
|
+
### copyright(c) 2007-2008 kuwata-lab.com all rights reserved.
|
7
|
+
###
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
|
11
|
+
spec = Gem::Specification.new do |s|
|
12
|
+
## package information
|
13
|
+
s.name = "cgi-exception"
|
14
|
+
s.author = "makoto kuwata"
|
15
|
+
s.email = "kwa(at)kuwata-lab.com"
|
16
|
+
s.rubyforge_project = 'cgi-exception'
|
17
|
+
s.version = "0.3.0"
|
18
|
+
s.platform = Gem::Platform::RUBY
|
19
|
+
s.homepage = "http://cgi-exception.rubyforge.org/"
|
20
|
+
s.summary = "Utility to display what and at where exception raised in CGI script"
|
21
|
+
s.description = <<-'END'
|
22
|
+
cgi-exception.rb is a tiny utility to display what and at where exception raised in CGI script just like PHP.
|
23
|
+
You don't need to look for error message in web server's log file.
|
24
|
+
END
|
25
|
+
|
26
|
+
## files
|
27
|
+
files = []
|
28
|
+
files += Dir.glob('lib/**/*.rb')
|
29
|
+
files += Dir.glob('test/**/*.rb')
|
30
|
+
files += %W[README.txt CHANGES.txt setup.rb #{s.name}.gemspec]
|
31
|
+
s.files = files
|
32
|
+
end
|
33
|
+
|
34
|
+
# Quick fix for Ruby 1.8.3 / YAML bug (thanks to Ross Bamford)
|
35
|
+
if (RUBY_VERSION == '1.8.3')
|
36
|
+
def spec.to_yaml
|
37
|
+
out = super
|
38
|
+
out = '--- ' + out unless out =~ /^---/
|
39
|
+
out
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if $0 == __FILE__
|
44
|
+
Gem::manage_gems
|
45
|
+
Gem::Builder.new(spec).build
|
46
|
+
end
|
data/lib/cgi_exception.rb
CHANGED
@@ -1,57 +1,82 @@
|
|
1
1
|
##
|
2
|
-
## $Rev:
|
3
|
-
## $Release: 0.
|
2
|
+
## $Rev: 16 $
|
3
|
+
## $Release: 0.3.0 $
|
4
4
|
## copyright(c) 2007-2008 kuwata-lab.com all rights reserved.
|
5
5
|
## License: public domain
|
6
6
|
##
|
7
7
|
|
8
|
-
|
9
|
-
def _esc_html(s)
|
10
|
-
s.to_s.gsub(/&/,'&').gsub(/</,'<').gsub(/>/,'>').gsub(/"/,'"')
|
11
|
-
end
|
8
|
+
class CGIExceptionPrinter
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
print "<pre style=\"color:#CC0000\">"
|
17
|
-
print "<b>#{_esc_html arr[0]}: #{_esc_html ex.message} (#{ex.class.name})</b>\n"
|
18
|
-
block = proc {|s| print " from #{_esc_html s}\n" }
|
19
|
-
max = 20
|
20
|
-
if arr.length <= max
|
21
|
-
arr[1..-1].each(&block)
|
22
|
-
else
|
23
|
-
n = 5
|
24
|
-
arr[1..(max-n)].each(&block)
|
25
|
-
print " ...\n"
|
26
|
-
arr[-n..-1].each(&block)
|
10
|
+
def initialize(skip_header=false, out=$stdout)
|
11
|
+
@skip_header = skip_header
|
12
|
+
@out = out
|
27
13
|
end
|
28
|
-
print "</pre>"
|
29
|
-
end
|
30
14
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
15
|
+
attr_accessor :skip_header, :out
|
16
|
+
|
17
|
+
## escape HTML characters
|
18
|
+
def escape_html(s)
|
19
|
+
s.to_s.gsub(/&/,'&').gsub(/</,'<').gsub(/>/,'>').gsub(/"/,'"')
|
20
|
+
end
|
21
|
+
|
22
|
+
alias h escape_html
|
23
|
+
|
24
|
+
## print http header
|
25
|
+
def print_header()
|
26
|
+
@out.print "Status: 500 Internal Error\r\n"
|
27
|
+
@out.print "Content-Type: text/html\r\n"
|
28
|
+
@out.print "X-CGI-Exception: 0.3.0\r\n"
|
29
|
+
@out.print "\r\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
## print exception in HTML format
|
33
|
+
def print_exception(ex)
|
34
|
+
arr = ex.backtrace
|
35
|
+
@out.print "<pre style=\"color:#CC0000\">"
|
36
|
+
@out.print "<b>#{h(arr[0])}: #{h(ex.message)} (#{h(ex.class.name)})</b>\n"
|
37
|
+
block = proc {|s| @out.print " from #{h(s)}\n" }
|
38
|
+
max = 20
|
39
|
+
if arr.length <= max
|
40
|
+
arr[1..-1].each(&block)
|
41
|
+
else
|
42
|
+
n = 5
|
43
|
+
arr[1..(max-n)].each(&block)
|
44
|
+
@out.print " ...\n"
|
45
|
+
arr[-n..-1].each(&block)
|
46
|
+
end
|
47
|
+
@out.print "</pre>"
|
48
|
+
end
|
49
|
+
|
50
|
+
def handle(exception)
|
51
|
+
print_header() unless @skip_header
|
52
|
+
print_exception(exception)
|
53
|
+
end
|
38
54
|
|
39
|
-
## print HTTP header (for mod_ruby)
|
40
|
-
def _print_http_header_for_modruby()
|
41
|
-
request = Apache::request
|
42
|
-
request.status = 500
|
43
|
-
request.status_line = '500 Internal Error'
|
44
|
-
request.content_type = 'text/html'
|
45
|
-
request.headers_out['X-CGI-Exception'] = '0.2.0'
|
46
|
-
request.send_http_header
|
47
55
|
end
|
48
56
|
|
49
|
-
if defined?(MOD_RUBY)
|
50
57
|
|
51
|
-
|
52
|
-
|
58
|
+
class ModRubyExceptionPrinter < CGIExceptionPrinter
|
59
|
+
|
60
|
+
## print HTTP header (for mod_ruby)
|
61
|
+
def print_header
|
62
|
+
request = Apache::request
|
63
|
+
request.status = 500
|
64
|
+
request.status_line = '500 Internal Error'
|
65
|
+
request.content_type = 'text/html'
|
66
|
+
request.headers_out['X-CGI-Exception'] = '0.3.0'
|
67
|
+
request.send_http_header
|
68
|
+
end
|
69
|
+
|
70
|
+
def print_exception(ex)
|
71
|
+
super
|
72
|
+
$stderr.write "#{ex.backtrace[0]}: #{ex.message} (#{ex.class.name})\n"
|
53
73
|
end
|
54
74
|
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
if defined?(MOD_RUBY)
|
79
|
+
|
55
80
|
class ::Apache::RubyRun # :nodoc:
|
56
81
|
## if 'alias _handler_orig handler' statement is evaluated
|
57
82
|
## more than twice, handler() will cause stack over flow.
|
@@ -59,13 +84,15 @@ if defined?(MOD_RUBY)
|
|
59
84
|
alias _handler_orig handler
|
60
85
|
end
|
61
86
|
## override handler() to catch and exception it to browser
|
62
|
-
def handler(
|
63
|
-
return _handler_orig(
|
87
|
+
def handler(request)
|
88
|
+
return _handler_orig(request)
|
64
89
|
rescue Exception => ex
|
65
|
-
|
66
|
-
|
90
|
+
#Apache.request.set_cgi_env unless ENV.key?("GATEWAY_INTERFACE")
|
91
|
+
ModRubyExceptionPrinter.new().handle(ex)
|
92
|
+
if defined?(EditorKicker)
|
93
|
+
EditorKicker.handle(ex) #if ENV['EDITOR_KICKER']
|
94
|
+
end
|
67
95
|
#raise ex
|
68
|
-
$stderr.write "#{ex.backtrace[0]}: #{ex.message} (#{ex.class.name})\n"
|
69
96
|
return ::Apache::OK
|
70
97
|
end
|
71
98
|
## original
|
@@ -80,9 +107,7 @@ if defined?(MOD_RUBY)
|
|
80
107
|
|
81
108
|
else
|
82
109
|
|
83
|
-
|
84
|
-
_print_http_header_for_cgi()
|
85
|
-
end
|
110
|
+
$_header_printed = false
|
86
111
|
|
87
112
|
## override $stdout.write() to detect whether HTTP header printed or not
|
88
113
|
class << $stdout
|
@@ -92,13 +117,14 @@ else
|
|
92
117
|
end
|
93
118
|
end
|
94
119
|
|
95
|
-
$_header_printed = false
|
96
|
-
|
97
120
|
## when process exit, print exception if exception raised
|
98
121
|
at_exit do
|
99
122
|
if $!
|
100
|
-
|
101
|
-
|
123
|
+
ex = $!
|
124
|
+
CGIExceptionPrinter.new($_header_printed).handle(ex)
|
125
|
+
if defined?(EditorKicker)
|
126
|
+
EditorKicker.handle(ex) #if ENV['EDITOR_KICKER']
|
127
|
+
end
|
102
128
|
end
|
103
129
|
end
|
104
130
|
|
data/test/test_cgi_exception.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
###
|
2
2
|
### $Rev: 7 $
|
3
|
-
### $Release: 0.
|
3
|
+
### $Release: 0.3.0 $
|
4
4
|
### copyright(c) 2007-2008 kuwata-lab.com all rights reserved.
|
5
5
|
###
|
6
6
|
|
@@ -43,7 +43,7 @@ END
|
|
43
43
|
@expected = <<END
|
44
44
|
Status: 500 Internal Error\r
|
45
45
|
Content-Type: text/html\r
|
46
|
-
X-CGI-Exception: 0.
|
46
|
+
X-CGI-Exception: 0.3.0\r
|
47
47
|
\r
|
48
48
|
<pre style="color:#CC0000"><b>when_no_header_printed.rb:3:in `build_html': undefined local variable or method `name' for main:Object (NameError)</b>
|
49
49
|
from when_no_header_printed.rb:5
|
@@ -99,7 +99,7 @@ END
|
|
99
99
|
@expected = <<END
|
100
100
|
Status: 500 Internal Error\r
|
101
101
|
Content-Type: text/html\r
|
102
|
-
X-CGI-Exception: 0.
|
102
|
+
X-CGI-Exception: 0.3.0\r
|
103
103
|
\r
|
104
104
|
<pre style="color:#CC0000"><b>when_error_backtrace_is_too_long.rb:6:in `f': stack level too deep (SystemStackError)</b>
|
105
105
|
from when_error_backtrace_is_too_long.rb:9:in `g'
|
@@ -129,7 +129,7 @@ END
|
|
129
129
|
@expected2 = <<END
|
130
130
|
Status: 500 Internal Error\r
|
131
131
|
Content-Type: text/html\r
|
132
|
-
X-CGI-Exception: 0.
|
132
|
+
X-CGI-Exception: 0.3.0\r
|
133
133
|
\r
|
134
134
|
<pre style="color:#CC0000"><b>when_error_backtrace_is_too_long.rb:9:in `g': stack level too deep (SystemStackError)</b>
|
135
135
|
from when_error_backtrace_is_too_long.rb:6:in `f'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cgi-exception
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- makoto kuwata
|
@@ -9,12 +9,12 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-07-19 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
16
|
description: cgi-exception.rb is a tiny utility to display what and at where exception raised in CGI script just like PHP. You don't need to look for error message in web server's log file.
|
17
|
-
email: kwa
|
17
|
+
email: kwa(at)kuwata-lab.com
|
18
18
|
executables: []
|
19
19
|
|
20
20
|
extensions: []
|
@@ -27,6 +27,7 @@ files:
|
|
27
27
|
- README.txt
|
28
28
|
- CHANGES.txt
|
29
29
|
- setup.rb
|
30
|
+
- cgi-exception.gemspec
|
30
31
|
has_rdoc: false
|
31
32
|
homepage: http://cgi-exception.rubyforge.org/
|
32
33
|
post_install_message:
|
@@ -49,7 +50,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
50
|
requirements: []
|
50
51
|
|
51
52
|
rubyforge_project: cgi-exception
|
52
|
-
rubygems_version: 1.0
|
53
|
+
rubygems_version: 1.2.0
|
53
54
|
signing_key:
|
54
55
|
specification_version: 2
|
55
56
|
summary: Utility to display what and at where exception raised in CGI script
|