-
Notifications
You must be signed in to change notification settings - Fork 102
Error Handling
You don't need to do anything special to message the user about errors (though it's polite to use the standard error when doing so). If you need to exit immediately due to an unrecoverable error, simply raise an exception; GLI will display the exception message to the user, but not the backtrace. In general, this is what you want and should work fine.
GLI will exit zero if no exception was raised. GLI will exit nonzero as follows:
- If there is a problem parsing the command line (e.g. unknown command, unknown flag), GLI exits with 64
- If your code raises an exception, GLI exits with 1
If you need to exit but don't have an exception to raise, you can use either exit_now!
or help_now!
. exit_now!
with raise
a CustomExit
for you with the mesage and optional exit status.
help_now!
will do the same, but will also redisplay the help for the command the user attempted to execute. This is useful for
sanity-checking command-line arguments.
If you need some very sophisticated error reporting and message codes, peppering your code with exit_now!
might lead to a mess. In this case, you could use CustomExit
as a base class for your exceptions:
class NoNetworkConnection < CustomExit
def initialize
super("No network connection was available", -4)
end
end
class BadInput < CustomExit
def initialize(message)
super(message, -5)
end
end
You could also mix in GLI::StandardException
to any exception that you get:
def doit
# some code that might raise
rescue => ex
ex.extends(GLI::StandardException)
raise
end
If you want to skip GLI's "catch exceptions, print the message, and exit nonzero" behavior, you can by using the on_error
hook.
For example:
on_error do |exception|
case exception
when NetworkProblem
$stderr.puts "Problem with the network: #{exception.message}"
false # skip GLI's error handling
when ArgumentError
$stderr.puts "Programmer made some mistake"
false # skip GLI's error handling
else
true # use GLI's default error handling
end
end
If the block evaluates to true
, GLI's error handling kicks in, but you can avoid that by having your block evaluate to false
.
Unless you have overridden the on_error
hook, GLI will not make the backtrace of any exceptions caught available. To cause GLI to print it, set the environment variable 'GLI_DEBUG' to 'true'. This is useful for debugging your application
$ bin/gli foo
error: Unknown command 'foo'
$ env GLI_DEBUG=true bin/gli foo
error: Unknown command 'foo'
/Users/davec/Projects/gli/lib/gli.rb:305:in `parse_options_helper': Unknown command 'foo' (GLI::BadCommandLine)
from /Users/davec/Projects/gli/lib/gli.rb:244:in `parse_options'
from /Users/davec/Projects/gli/lib/gli.rb:139:in `run'
from bin/gli:70
This should also work when running system tests:
$ GLI_DEBUG=true rake cucumber