Exception and error handling
P4Java uses a small set of Java exceptions to signal errors that have occurred in either the Helix Server as a result of issuing a specific command to the server, or in the P4Java plumbing in response to things like TCP/IP connection errors or system configuration issues. (These exceptions are not used to signal file operation problems at the individual file level — see Helix Server file operations for details about individual file error handling.)
In general, P4Java exceptions are rooted in two different classes: the
P4JavaException
classes are intended for “normal” (that is,
recoverable) errors that occur as the result of things like missing
client files, a broken server connection, or an inappropriate command
option; the P4JavaError
classes are intended for more
serious errors that are unlikely to be recoverable, including unintended
null pointers or P4Java-internal errors. The P4JavaException
class hierarchy is rooted in the normal java.lang.Exception
tree, and any such exception is always declared in relevant method
“throws” clauses; the P4JavaError
classes, however, are
rooted in java.lang.Error
, and consequently do not need to
be declared or explicitly caught. This allows a developer to catch all
such P4JavaErrors, for example, in an outer loop, but to process
“normal” P4JavaExceptions in inner blocks and loops as they occur.
Typically, application code should report a P4JavaError
exception and then terminate either itself or whatever it was doing as
soon as possible, as this exception indicates a serious error within
P4Java. P4JavaException
handling is more fine-grained and
nuanced: A P4JavaException
almost always signals a
recoverable (or potentially-recoverable) error, and should be caught
individually or at the class level. The following snippet represents a
common pattern for P4Java
error and exception handling
around major functional blocks or processing loops:
try {
// issue one or more server or client commands...
} catch (P4JavaError err) {
panic(err); // causes app to exit after printing message to stderr...
} catch (RequestException rexc) {
// process server-side Perforce error...
} catch (ConnectionException cexc) {
// process Perforce connection exception...
} catch (P4JavaException exc) {
// catchall...
} catch (Exception exc) {
// Other-exception catchall...
}
Note the way RequestException
and
ConnectionException
events are handled separately:
RequestException
exceptions are almost always thrown in
response to a Helix Server error message and therefore include a
severity and generic code that can be used or displayed (other
P4JavaExceptions
do not usually contain these), and
ConnectionExceptions
should normally result in the enclosing
app explicitly closing or at least re-trying the associated connection,
as processing can no longer continue on the current
Helix Server
connection.