This is really great - seeing Ruby errors definitely makes things more clear.

So, to test this all out, here's what my "index.cgi" looks like:
#! /usr/bin/ruby
require 'cgicroak'

CGI.croak('html4') do |cgi|
	cgi.out("type" => "text/html") {"shizzle"}
end

This works as expected. The word shizzle makes it to the browser.

However, when I execute this:
#! /usr/bin/ruby
require 'cgicroak'

CGI.croak('html4') do |cgi|
	cgi.out("type" => "image/gif") {File.open("image.gif")}
end

I get:
Error NameError: undefined method `length'

I get the same thing with:
#! /usr/bin/ruby
require 'cgicroak'

CGI.croak('html4') do |cgi|
	cgi.out("type" => "image/gif", "length" => File.size("image.gif"))
{File.open("image.gif")}
end

In either cases, if I use cgi.header instead of cgi.out, I get an error saying:
"No header sent"

Any ideas about what's going on?

On 4/20/05, Paul Battley <pbattley / gmail.com> wrote:
> I have found that you need to write the header manually, despite what
> the docs say.
> 
> This snippet will save you a lot of hassle whilst developing under
> CGI.  It should trap errors and give a backtrace in the browser, as
> well as indicate if you didn't send the header properly:
> 
> ---- cgicroak.rb ----
> 
> require 'cgi'
> 
> class CGI
>     def self.croak(*args)
>         cgi = CGI.new(args)
>         old_stdout = $stdout
>         buffer = ''
>         def buffer.write(s)
>             self << s
>         end
>         $stdout = buffer
>         begin
>             yield(cgi)
>             unless (buffer =~ /^Content-type:.*?\r?\n\r?\n/i)
>                 raise RuntimeError, "No header sent"
>             end
>         rescue Exception => e
>             buffer.replace('')
>             print(cgi.header('type' => 'text/plain'))
>             puts("Error\n\n")
>             puts("#{e.class.to_s}: #{e.to_s}\n\n")
>             puts(e.backtrace.join("\n"))
>         end
>         $stdout = old_stdout
>         $stdout.write(buffer)
>     end
> end
> 
> ---- index.cgi ----
> 
> #!/path/to/your/ruby
> 
> require 'croakcgi'
> 
> CGI.croak('html4') do |cgi|
> 
>     # Your requires go here
> 
>     print(cgi.header)
> 
>     # Your code
> 
> end
> 
> --- EOF ---
> 
> Paul.
> 
>