Help - redirect/flush/sync problem

rubyists-

i thought i understood redirection, untill this:

#!/usr/local/bin/ruby

$stderr.reopen File.open ‘stderr’, ‘w’
$stderr.sync = true
$defout.sync = true

foo # this raises an exception…

$defout.flush
$defout.close
$stderr.flush
$stderr.close

puts IO.readlines ‘stderr’, ‘r’

i was expecting to see

foo.rb:7: undefined local variable or method `foo’ for #Object:0x401dbce0 (NameError)

which IS in fact writtne to the file ‘stderr’, but not untill AFTER the script
finishes? what gives?

i wanted to use this technique to catch NameErrors errors from cgi scripts…

-a

···

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

  foo # this raises an exception...

This raises an exception and you don't catch it. Consequence the error
message is printed in 'stderr' when ruby exit (i.e. it don't execute the
lines after the error)

Guy Decoux

nope.

#!/usr/bin/env ruby

begin
$stderr.reopen File.open ‘stderr’, ‘w’
$stderr.sync = true

foo # this raises an exception…

ensure
$stderr.flush

puts IO.readlines ‘stderr’, ‘r’
puts FILE
end

this outputs only ‘foo.rb’

eli > ruby foo.rb
foo.rb

eli > cat stderr
foo.rb:9: undefined local variable or method `foo’ for #Object:0x401dbce0 (NameError)

so the file IS created… this is really bizare…

is it a bug in ruby?

here is another hint : if i also do $stderr.close after $stderr.flush, the file
is not even created!

-a

···

On Sat, 9 Nov 2002, ts wrote:

This raises an exception and you don’t catch it. Consequence the error
message is printed in ‘stderr’ when ruby exit (i.e. it don’t execute the
lines after the error)

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

[[ apparently you use a strange newsreader which don't signal the Cc:]]

  foo # this raises an exception...

  the exception is not caught

ensure
  $stderr.flush

  puts IO.readlines 'stderr', 'r'
  puts __FILE__
end

so the file IS created... this is *really* bizare....

ruby treat the exception when it finish

here is another hint : if i also do $stderr.close after $stderr.flush, the file
is not even created!

Normal it can't write in the file, you have closed it :-)))

Guy Decoux

Another remark

  puts IO.readlines 'stderr', 'r'

                                 ^^^
                                 >>>

You really want this ?

Guy Decoux

i think the problem is that NameError does not subclass StandardError, because
this does work :

begin
$stderr.reopen File.open ‘stderr’, ‘w’
$stderr.sync = true
foo # this raises an exception…
rescue NameError => err
$stderr.puts err
ensure
$stderr.flush
puts IO.readlines ‘stderr’
end

irb(main):001:0> NameError.new
#<NameError: NameError>

irb(main):002:0> NameError.new.is_a? StandardError
false

does anyone know why this is?

-a

···

On Sun, 10 Nov 2002, ts wrote:

ruby treat the exception when it finish

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

i think the problem is that NameError does not subclass StandardError, because
this *does* work :

No, not really

rescue NameError => err
  $stderr.puts err

This time you have caught the exception

Try with this

pigeon% cat b.rb
#!/usr/bin/ruby
begin
  $stderr.reopen File.open 'stderr', 'w'
  $stderr.sync = true
  1/0
ensure
  $stderr.flush
  puts IO.readlines 'stderr'
end
pigeon%

pigeon% b.rb
pigeon%

pigeon% cat stderr
./b.rb:5:in `/': divided by 0 (ZeroDivisionError)
        from ./b.rb:5
pigeon%

Guy Decoux

No, not really
[snip]
This time you have caught the exception
[snip]

what i was getting at was that i wasn’t catching ALL exceptions… what i have
now is


rescue NameError => err
$stderr.puts err
rescue => err
$stderr.puts err

and this works for both examples (foo, 1/0)… i was under the impression
that a :

rescue => err

clause would catch all errors, since i thought all errors were subclasses of
StandardError - this obviously is not the case. since i had to explicitly
catch the NameError in order to redirect to file. my goal was to redirect ALL
stderr to file in cgi programs, since any stderr output causes apache to print
an error page, and also catch all exceptions - in this was, i can generate
meaningfull error pages when debugging cgi programs. any better ways to do
this you know of? the advantage of this technique is that one can check to
see if anything was written the stderr file, and decide what to do then, if
$stderr is not redirected you do not have this option.

-a

···

On Sun, 10 Nov 2002, ts wrote:

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================