From: Brian Candler Date: 2003-07-30T16:27:27+09:00 Subject: Re: cgi traceback --a8Wt8u1KmwUX3Y2C Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Jul 30, 2003 at 11:05:52AM +0900, Jesper Olsen wrote: > Is there a way to configure the ruby cgi module to give > trace back information incase of errors in the script? > > Similar to pythons cgitb (cgitb.enable())... You can just trap the exception and display it. The attached code uses the ruby-fcgi library (which I recommend anyway - your application then runs either as cgi or fcgi with no modification), but you can just extract the begin-rescue-end bit for your use. Regards, Brian. --a8Wt8u1KmwUX3Y2C Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="base.rb" # Trivial CGI/FCGI application framework. Runs 'handle' for each request # and has a last-ditch exception catcher # TODO: # - Allow stylesheet customisation of error page # - Hook to allow logging of exceptions (or logging in general) require 'fcgi' module FCGIApp class Base def initialize(cgi) @cgi = cgi @done_header = false end def header(*args) return if @done_header print @cgi.header(*args) @done_header = true end def end_request throw :end_request end def param(name) @cgi.params[name][0] # works under both 1.6/1.8 without warnings end def env(name) @cgi.env_table[name] end REDIRECT_PAGE = < Moved Please click here to continue EOS def redirect(url, status='301 Moved Temporarily') header( 'Status'=>status, 'Location'=>url ) printf( REDIRECT_PAGE, url ) end_request end # def handle: virtual (does the actual work of processing one request) def self.run(*htmlgen) FCGI.each_cgi(*htmlgen) do |cgi| begin app = self.new(cgi) catch(:end_request) do app.handle end rescue Exception => detail app ? app.header : (print cgi.header) print < Internal error in #{$0}

Internal error in #{$0}

#{CGI.escapeHTML(detail.message.to_s)} EOS puts "
#{CGI.escapeHTML(detail.backtrace.join("\n"))}
" if detail.backtrace puts "" end end end end # class Base end # module FCGIAPP --a8Wt8u1KmwUX3Y2C Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="app1.rb" #!/usr/local/bin/ruby -w # Simple application which makes no use of templates or cookies. # When run under fastcgi you will see the run counter incrementing, # proving that it's a persistent process. $:.unshift('../lib') require 'fcgiapp/base' class MyApp < FCGIApp::Base @@runcount = 0 def handle @@runcount += 1 #cmd = @cgi['command'][0] # ruby 1.6/1.8, but warns under 1.8 #cmd = @cgi['command'] # ruby 1.8 only cmd = param('command') # portable but a tad less efficient case cmd when nil header puts "" puts "I am PID #{Process.pid} and have run #{@@runcount} times
" puts "
" puts "" puts "" puts "" puts "" puts "
" when 'add' ans = param('v1').to_i + param('v2').to_i header puts "The answer is #{ans}" when 'news' redirect "http://news.bbc.co.uk/" else header puts "Sorry, unknown command #{CGI.escapeHTML(cmd)}" end end end MyApp.run --a8Wt8u1KmwUX3Y2C--