rubyexceptionerror-handlingexitbacktrace

Write a simple error message without a backtrace


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:


Solution

  • 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.