Overview¶
Offline applications should be designed with ability to handle any errors and conflicts.
Offline OData Errors¶
The SAPOfflineOData
framework generates three types of errors:
- Common OData errors
- Offline-specific errors
- Business logic failures
Common OData Errors¶
OfflineODataProvider
conforms to the DataServiceProvider
interface, which is declared in SAPOData
framework. OfflineODataProvider
raises DataServiceError
(declared in the OData Swift framework) or DataServiceException
(declared in the OData Java framework) in implemented functions declared in DataServiceProvider
.
Offline-Specific Errors¶
Offline-specific methods, such as open, upload, and download, raise OfflineODataError
(for iOS) or OfflineODataException
(for Android). These errors generally fall into the following categories:
- Invalid Input The input of the operation is invalid.
- Precondition Failed The precondition has not been met and, as a result, the operation is blocked.
- Not Found The target that the current operation is trying to process cannot be found.
- Not Supported The operation is not supported.
- Communication Error Communication with the server has been interrupted.
- Server Side Error A server-side issue has occurred.
- Client Internal Error An internal issue has occurred on the client side.
Each category is represented by an enumeration case in Swift and a subclass of OfflineODataException
in Java.
Each error (OfflineODataError
or OfflineODataException
) consists of the following fields:
errorName
An enum name identifying the error type. See Offline errors sorted by name for a list of all error types sorted by name.errorCode
A numeric code identifying the error type. See Offline errors sorted by code for a list of all error types sorted by code.message
A detailed description of the error.
The following code example shows how to process offline-specific errors:
try {
//Function call here
...
} catch( OfflineODataInvalidInputException invalidInputException ) {
OfflineODataErrorName errorName = invalidInputException.getErrorName();
switch( errorName ) {
case DuplicateKeyProperty:
...
break;
case NotPositiveTop:
...
break;
default:
...
}
} catch ( ... ) // Other relative exception catching.
{
... //Other relative exception processing
} catch( OfflineODataException offlineException ) { //General offline exception catching
OfflineODataErrorName errorName = offlineException.getErrorName();
int errorCode = offlineException.getErrorCode();
...
}
do {
//Function call here
...
} catch OfflineODataError.invalidInput(let errorCode, let errorMessage) {
let errorName = OfflineODataErrorName(rawValue:errorCode)
switch errorName {
case .duplicateKeyProperty:
...
case .notPositiveTop:
...
default:
...
}
...
} catch ... { // Other relative exception catching.
... //Other relative exception processing
} catch let error as OfflineODataError { //General offline exception catching
}
...
}
Business Logic Failures¶
Business logic errors may occur at the OData back-end service, preventing a change when a client calls theupload()
function of OfflineODataProvider
. These errors are not generated by the Offline OData SDK, nor mobile services. These errors are not reflected in function calls but are recorded in the ErrorArchive
, an offline specific entity set containing detailed information about errors. The application can obtain the body of the original request from ErrorArchive
. This is discussed in detail in "Handling Failed Requests."
Offline OData Conflicts¶
Conflicts are specific types of errors that arise when multiple clients simultaneously modify the same data in the back end. An offline application should include a process that either avoids conflicts, or logs and resolves them when they arise.
OData services use ETags
to identify conflicts. An ETag
is an identifier that is assigned to a specific version of an entity. When an entity is modified, a new ETag
is assigned.
To use ETags
to detect conflicts in your application:
-
The application retrieves an entity, along with its
ETag
, from the offline store. -
When an update request is made, the application sends the request, along with the original
ETag
, to the offline store. ` -
If the
ETag
that is provided with the update request matches what is currently in the offline store, the update is performed locally and a newETag
is generated. The request and theETag
are added to the request queue. If theETag
does not match, an error is generated. -
When an upload is performed, the request and the
ETag
are sent to the OData service. If theETag
matches the one in the OData service, the update is performed and the updated entity plus a newETag
are retrieved by the application during the next download. If theETag
does not match, the request will fail, the error is put in theErrorArchive
and the application then determines how to proceed.
Usually when an update results in an ETag
conflict, the offline store may need to present the latest state from the back end with the modified state so that the application can decide whether additional changes are necessary. A download, possibly with a limited set of defining queries, might need to be done. When the download completes, the offline store has the latest ETag
and data. From the offline store, the application can only see the latest state from the back end with the associated pending requests applied. If you require the latest state from the back end for proper handling of the conflict, you may choose to remove entries in the ErrorArchive
. This will cause removal of all requests in error as well and associated entities returning to server state. This will be discussed further in Handling Failed Requests.