public interface ErrorHandling
RPCResponse
and DSResponse
objects have an integer status field that the
RPCManager inspects when the response is received from the server. If the value of this
field is less than zero, the request is considered to have failed. Otherwise it is
considered to have succeeded. This value is settable via the setStatus() method call
on the server-side DSResponse and RPCResponse objects.
Errors in a Smart GWT application fall into two main categories:
STATUS_VALIDATION_ERROR
validation
of a form results in
errors, the form is redrawn to
display those errors to the user. How the user sees those errors is completely configurable -
for example, see the DynamicForm properties showErrorIcons
,
showErrorText
,
showInlineErrors
, and
indeed most DynamicForm properties
that contain the workd "Error" - but the default in most skins is to highlight the field
with some kind of error icon, and provide the actual error text message in a floating box
when the user hovers over the field.
The remainder of this article concerns unrecoverable errors. These are errors with the system itself, for example:
DSRequest
calls default to centralized
handling;
RPCRequest
calls default to user error handling in the
callback.
Centralized Error Handling
If the status field shows a failure, the RPCManager will invoke
HandleErrorCallback.handleError()
. By default, this logs a warning and shows a dialog
with the contents of the response's data
field (which is assumed
to contain a meaningful description of the error that occurred). If you specified a
callback in your request, it will not be called if the status shows a failure
(see the section on custom error handling below for how to change this). This default
arrangement means that any Smart GWT application has a basic handling mechanism for
unrecoverable errors, without any code to write.
You can customize centralized error handling at two levels:
RPCManager.setHandleErrorCallback(com.smartgwt.client.rpc.HandleErrorCallback)
to provide your own error handling logic (note
that customization takes place at the static class level, not per-instance)RPCManager.setHandleTransportErrorCallback(com.smartgwt.client.rpc.HandleTransportErrorCallback)
.
This logic is called earlier than
handleError, and it is called even when you are using custom error handling (discussed
below). It is intended to allow your code to inspect the failed response early in the
handling flow, to see if it is really unrecoverable. For example, a failure might have
happened because of a temporary network problem, so resubmitting the request may be a valid
thing to do to try to resolve the error. Note, as with handleError, this is a static
class-level customization
Custom Error Handling
As an alternative to handling errors centrally, you can handle them in your regular callback
methods. To do this, specify willHandleError
as a
request property. When you do this, centralized error handling is bypassed (as mentioned
above, handleTransportError()
will still be called) and your callback is
invoked as normal. Your callback code determines that it is in error state by inspecting
the status property on the response - if it is negative, there has been an error. Note
that validation errors are treated specially, in that your callback is invoked, but the
normal behavior of populating the field errors onto the form and redrawing it also
takes place.
Note, when you are handling errors in user callbacks, a negative status in the response
indicates some sort of serious, unrecoverable error (except in the case of
STATUS_VALIDATION_ERROR
).
Therefore, ensure that your error handling
code does not assume that the response will be properly formed or contain particular
elements.
You can specify willHandleError
(or any other DSRequest/RPCRequest property)
on a component request by providing the DSRequest Properties parameter. For example, on
a ListGrid.fetchData()
:
DSRequest properties = new DSRequest(); properties.setWillHandleError(true); listGrid.fetchData(new Criteria(), new DSCallback() { public void execute(DSResponse response, Object rawData, DSRequest request) { if (response.getStatus() < 0) { // Error handling here } else { // Normal processing here } } }, properties);Error Status Codes
RPCResponse class
. Status codes in the range -1 to
-100 are
reserved for use by the framework; if you wish to introduce new custom error statuses for
your own use, avoid this range.
Errors indicating login is required
Some of the framework error statuses indicate that login is required, typically because a
user's HTTP session has timed out. The best way to handle this situation is to use the
built-in re-login flow
to automatically prompt users
to log back
in as required, and then resubmit the requests that triggered the login required response.
Errors during a file download
Any error that occurs during an operation that involves file download will not trigger
HandleErrorCallback.handleError()
and the centralized error handling pathway. This includes:
exportData()
,
exportClientData()
, or
exportContent()
.
DataSource.downloadFile()
RPCRequest.downloadResult
flag is set
If you have an error condition that could arise in the middle of a file download, best practice is to:
For built-in download operations such as exportData()
, if your DataSource or
custom logic throws an exception or returns an error DSResponse
, the default
behavior of the Server Framework is indeed to return a valid file containing the error
message.
com.smartgwt.client.data.DataSource#getSimpleErrors
,
HandleErrorCallback.handleError(com.smartgwt.client.data.DSResponse, com.smartgwt.client.data.DSRequest)
,
RPCManager.runDefaultErrorHandling(com.smartgwt.client.data.DSResponse, com.smartgwt.client.data.DSRequest)
,
HandleTransportErrorCallback.handleTransportError(int, int, int, java.lang.String)
,
ErrorEvent
,
FormItem.clearErrors()
,
FormItem.setErrors(java.lang.String)
,
FormItem.hasErrors()
,
DSResponse.getStatus()
,
DSResponse.getQueueStatus()
,
DSResponse.getErrors()
,
com.smartgwt.client.data.DSRequest#getCallback
,
com.smartgwt.client.rpc.RPCRequest#getCallback
,
RPCRequest.getWillHandleError()