There's an inconsistency in the way CLIF handles exceptions in the Command validate() and run() methods, which is apparent when Application handle_exception() is overridden.
In Commmand run() you can say something like:
if ($write_error) {
MyApp::RunError::Write->throw(message => "error on $stream");
}
Then in Application handle_exception() something like:
sub handle_exception {
my ($self, $e) = @_;
if (ref($e) eq 'CLI::Framework::Exception::CmdRunException') {
my $encapsulated_exception = $e->error();
if (ref($encapsulated_exception) eq 'MyApp::RunError::Write') {
...
...
}
}
}
Command::dispatch includes the line:
throw_cmd_run_exception( error => $e );
However, the corresponding line for a validation error is:
throw_cmd_validation_exception( error => $e->error );
which means you need to issue exceptions in validate() differently from run(). For instance:
if ($missing_parm) {
MyApp::SyntaxError::Missing->throw(error => {
type => 'Missing',
message => 'missing parameter after foo request',
}
);
}
and in Application::handle_exception:
if (ref($e) eq 'CLI::Framework::Exception::CmdValidationException') {
my $error = $e->error();
if (($error->{type} eq 'Missing') {
...
...
}
}
It's not possible to pull out the encapsulated exception, as it is for a run exception, and you need to resort to an ad-hoc way to encode the information handle_exception() might need, such as an anonymous hash.
In fact, since first drafting this message I've decided not to use validate(), but I suggest it would be a good idea to make all CLIF exceptions consistent with Command run(), that is, to write:
throw_XXX_exception( error => $e );
|