com.smartgwt.client.docs

## Interface ErrorHandling

-     public interface ErrorHandling

  ### Error Handling Overview

  `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:

  - Validation errors, which arise as a result of rules in the application's business logic being broken. These are part of the normal operation of the system. A response with validation errors has a status of `STATUS_VALIDATION_ERROR`
  - Unrecoverable errors, which are errors with the system itself. These are not part of the normal operation of the system
  Validation errors are treated differently from other errors, precisely because they are an expected part of the normal operation of the system. If `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:

  - A network transport problem
  - A server-side crash
  - An update failed because a transaction was rolled back
  Errors like this can either be handled centrally, or you can choose to handle them in your regular callback code. `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:

  - Use `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)
  - Use `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
  The error status codes used by the framework are documented as class variables of the `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:

  - export operations such as `exportData()`, `exportClientData()`, or `exportContent()`.
  - downloading of binary field values via `DataSource.downloadFile()`
  - custom download operations where the `RPCRequest.downloadResult` flag is set
  .. and, in general, any situation where the browser's "Save As.." dialog appears to the user, or the user's browser launches a helper application to view a file (such as Microsoft Excel).

  If you have an error condition that could arise in the middle of a file download, best practice is to:

  - pre-validate the request: do an ordinary, non-download request to check all common error conditions, before the request that actually initiates a download. This can avoid problems like a user who tries to download after their session has timed out, or tries to download a file that another user has deleted
  - return a valid file containing a user-friendly error message: for example, if the download is for an Excel spreadsheet but the database was unexpectedly unavailable, return a valid spreadsheet containing just the error message.

  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.

  See Also:
    `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)`, `FormItem.clearErrors()`, `FormItem.setErrors(java.lang.String)`, `FormItem.hasErrors()`, `ErrorEvent`, `DSResponse.getStatus()`, `DSResponse.getQueueStatus()`, `DSResponse.getErrors()`, `com.smartgwt.client.data.DSRequest#getCallback`, `com.smartgwt.client.rpc.RPCRequest#getCallback`, `RPCRequest.getWillHandleError()`