I want to write to either STDOUT
or STDERR
a clean, simple error message for the user, without the (verbose) backtrace. I am currently using raise
to write the error message and exit, as in this simplified example:
#!/usr/bin/env ruby
def bar
raise "this needs to be clean, no backtrace"
end
bar
It writes this to STDERR
:
/Users/foo/test/test1.rb:4:in `bar': this needs to be clean, no backtrace (RuntimeError)
from /Users/foo/test/test1.rb:7:in `<main>'
I want to write just this part:
this needs to be clean, no backtrace
The real-life example has a much more verbose backtrace, and multiple raise
statements to handle different failure modes with customized messages.
I am aware that I can do something like this (for clean STDOUT
), but I want to avoid repetitive code:
puts "this needs to be clean, no backtrace"
raise "this needs to be clean, no backtrace"
Related:
raise
- or something similar - to terminate the program immediately, and (b) print just the error message, not the full stack trace or backtrace, which is confusing for our users.If you just want to output to stderr, you could use warn
(or write to $stderr
directly), maybe along with exit
:
def bar
warn "this needs to be clean, no backtrace"
exit(false)
end
bar
To alter the way global exception handlers work, you could register an at_exit
handler which checks for the exception class, prints its message and silences stdout in order to suppress the backtrace. Something like this:
class SimpleError < StandardError ; end
at_exit do
if $!.is_a?(SimpleError)
$stderr.puts($!.message)
$stderr.reopen(IO::NULL)
end
end
def bar
raise SimpleError, "this needs to be clean, no backtrace"
end
bar
It would probably be a good idea to make that kind of error handling optional.