handle_error connection event

Executed whenever the MobiLink server encounters a SQL error.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

In SQL scripts, you can specify event parameters by name or with a question mark, but you cannot mix names and question marks within a script. If you use question marks, the parameters must be in the order shown below and are optional only if no subsequent parameters are specified (for example, you must use parameter 1 if you want to use parameter 2). If you use named parameters, you can specify any subset of the parameters in any order.

Parameter name for SQL scripts

Description

Order

s.action_code

INTEGER. This is an INOUT parameter.

1

s.error_code

INTEGER

2

s.error_message

TEXT

3

s.remote_id VARCHAR(128). The MobiLink remote ID. You can only reference the remote ID if you are using named parameters. Not applicable

s.username

VARCHAR(128). The MobiLink user name.

4

s.table

VARCHAR(128). If the script is not a table script, the table name is null.

5

Default action

When no handle_error script is defined or this script causes an error, the default action code is 3000: roll back the current transaction and cancel the current synchronization.

Remarks

The MobiLink server sends in the current action code. Initially, this is set to 3000 for each set of errors caused by a single SQL operation. Usually, there is only one error per SQL operation, but there may be more. This handle_error script is called once per error in the set. The action code passed into the first error is 3000. Subsequent calls are passed in the action code returned by the previous call. MobiLink uses the highest numerical value returned from multiple calls.

You can modify the action code in the script, and return a value instructing MobiLink how to proceed. The action code tells the MobiLink server what to do next. Before it calls this script, the MobiLink server sets the action code to a default value, which depends upon the severity of the error. Your script may modify this value. Your script must return or set an action code.

The action code parameter takes one of the following values:

  • 1000   Skip the current row and continue processing.

  • 3000   Roll back the current transaction and cancel the current synchronization. This is the default action code, and is used when no handle_error script is defined or this script causes an error.

  • 4000   Roll back the current transaction, cancel the synchronization, and shut down the MobiLink server.

The error codes and message allow you to identify the nature of the error. If the error happened as part of synchronization, the user name is supplied. Otherwise, this value is null.

The MobiLink server executes this script if an ODBC error occurs while MobiLink is processing an insert, update, or delete script during the upload transaction or is fetching download rows. If an ODBC error occurs at another time, the MobiLink server calls the report_error or report_ODBC_error script and aborts the synchronization.

If the error happened while manipulating a particular table, the table name is supplied. Otherwise, this value is null. The table name is the name of a table in the client application. This name may or may not have a direct counterpart in the consolidated database, depending upon the design of the synchronization system.

SQL scripts for the handle_error event must be implemented as stored procedures.

You can return a value from the handle_error script one of the following ways:

  • Pass the action parameter to an OUTPUT parameter of a procedure:

    CALL my_handle_error( {ml s.action_code}, {ml s.error_code}, {ml s.error_message}, {ml s.username}, {ml s.table} )
  • Set the action code via a procedure or function return value:

    {ml s.action_code} = CALL my_handle_error( {ml s.error_code}, {ml s.error_message}, {ml s.username}, {ml s.table} )

    Most RDBMSs use the RETURN statement to set the return value from a procedure or function.

The CustDB sample application contains error handlers for various database-management systems.

See also
SQL example

The following example works with a SQL Anywhere consolidated database. It allows your application to ignore redundant inserts.

The following call to a MobiLink system procedure assigns the ULHandleError stored procedure to the handle_error event.

CALL ml_add_connection_script(
    'ver1',
    'handle_error',
    'CALL ULHandleError(
      {ml s.action_code}, 
      {ml s.error_code}, 
      {ml s.error_message}, 
      {ml s.username}, 
      {ml s.table} )' )

The following SQL statement creates the ULHandleError stored procedure.

CREATE PROCEDURE ULHandleError(
   INOUT action integer,
   IN error_code integer,
   IN error_message varchar(1000),
   IN user_name varchar(128),
   IN table_name varchar(128) )
BEGIN
  -- -196 is SQLE_INDEX_NOT_UNIQUE
  -- -194 is SQLE_INVALID_FOREIGN_KEY
  IF error_code = -196 or error_code = -194 then
      -- ignore the error and keep going
      SET action = 1000;
  ELSE
      -- abort the synchronization
      SET action = 3000;
  END IF;
END
Java example

The following call to a MobiLink system procedure registers a Java method called handleError as the script for the handle_error connection event when synchronizing the script version ver1.

CALL ml_add_java_connection_script(
    'ver1',
    'handle_error',
    'ExamplePackage.ExampleClass.handleError' )

The following is the sample Java method handleError. It processes an error based on the data that is passed in. It also determines the resulting error code.

public String handleError(
  ianywhere.ml.script.InOutInteger actionCode,
  int errorCode,
  String errorMessage,
  String user,
  String table ) {
  int newAC;
  if( user == null ) {
    newAC = handleNonSyncError( errorCode,
    errorMessage ); }
  else if( table == null ) {
    newAC = handleConnectionError( errorCode,
    errorMessage, user ); }
  else {
    newAC = handleTableError( errorCode,
    errorMessage, user, table ); 
  }
  // Keep the most serious action code.
  if( actionCode.getValue() < newAC ) {
    actionCode.setValue( newAC ); 
  }
}
.NET example

The following call to a MobiLink system procedure registers a .NET method called HandleError as the script for the handle_error connection event when synchronizing the script version ver1.

CALL mll_add_dnet_connection_script(
  'ver1',
  'handle_error',
  'TestScripts.Test.HandleError' )

The following is the sample .NET method HandleError.

public string HandleError() (
  ref int actionCode,
  int errorCode,
  string errorMessage,
  string user,
  string table ) {
  int new_ac;
  if( user == null ) {
    new_ac = HandleNonSyncError( errorCode,
    errorMessage ); }
  else if( table == null ) {
    new_ac = HandleConnectionError( errorCode,
    errorMessage, user ); }
  else {
    new_ac = HandleTableError( errorCode,
    errorMessage, user, table ); 
  }
  // Keep the most serious action code.
  if( actionCode < new_ac ) {
    actionCode = new_ac; 
  }
}