Return values, Errors, and Exceptions

During import and export, the methods can provide error information to the sync engine. These errors can be returned on an object level or as a fatal exception.

There are some well-known exceptions that can be used, such as ServerDownException, to indicate a fatal problem that should stop the run from continuing. Unless the problem is one of the well-known exceptions, throwing one should be avoided. A custom exception shows up in the sync engine UI as a general failure and only the stack trace in the eventlog would provide additional information. It is instead expected that the error is returned on the object that caused the problem. Even an object-level error can stop a run.

An object-level error is returned by creating a Microsoft.MetadirectoryServices.CSEntryChangeResult in response to the object.

For password sync export operations, all errors are returned as exceptions.

The errors can be categorized into the following:

  • Well-known exceptions

Export errors, defined in Microsoft.MetadirectoryServices.MAExportError

  • Export errors, object-level
  • Export actions

Import errors, defined in Microsoft.MetadirectoryServices.MAImportError

  • Import errors, fatal
  • Import errors, object-level

In the sync engine, there are both errors and warnings. A run in the sync engine can have 5000 errors before the sync engine terminates the run. There can be 100,000 warnings before the same happens. The connector can only return errors. Warnings are currently only available for built-in functionality in the sync engine.

Well-known exceptions

This is a list of the most common well-known exceptions that could be used in a connector to indicate a fatal problem.

  • ServerDownException The server does not exist. Cannot even establish a connection to the remote server. This is the equal of a failed ping.
  • BadServerCredentialsException The credentials provided does not work. The expectation is that the administrator changes the credentials, like resetting the password, before the connector is able to work again.
  • FailedConnectionException The server is up (responds to ping), the credentials work, but for some other reason a connection cannot be established.
  • DroppedConnectionException Used when the connector could earlier in the run connect to the remote server, but for some reason is no longer able to connect to it.

There are many other exceptions, but these have been superseded by object-level errors.

Export errors, object level

What used to exceptions in earlier versions of the sync engine, is in ECMA2 an error returned on the object that caused the problem.

This list can be found on MSDN

In addition, there are also two special errors that allow you to return a custom error text to the administrator:

  • ExportErrorCustomContinueRun An error on the object, but the sync engine should continue to process other objects.
  • ExportErrorCustomStopRun An error on the object. It is fatal and no other object should be tried to be exported.

When using these errors, you should also use the overloaded version of CSEntryChangeResult that allows you to pass back the errorName and errorDescription. The errorName is a short text that would appear in the operations log in the sync engine UI. It can be anything, but tradition says that spaces are replaced by dashes so it looks something like "invalid-characters-error". The errorDescription is additional information that allows the administrator to understand the problem in detail. This information appears as a pop-up in the sync engine UI when the administrator clicks the error link.

Export actions

There are some return values that do not indicate an error, but that the connector has detected a situation in the target directory that wasn't expected. But the sync engine should be able to fix the problem without involving the administrator to take an action.

These actions also have a corresponding object level error when an action should not be taken by the sync engine.

  • ExportActionConvertUpdateToAdd The connector received an update to an object, but when looking in the target, it is no longer there. It might have been deleted manually in the target or lost in a replication conflict. An import and sync would stage the object to be recreated, but the connector can return this action instead. It would change it from an update to an add and in the next export batch, the object comes back with all attributes.
  • ExportActionProvisioningParent This action is useful when the DN-style is LDAP. When the connector tries to write an object, it detects that the parent OU isn't present. With this action, the sync engine comes back in the next batch with information on how to provision the parent OU. When the parent OU has been created in the target directory, the original object comes back to the connector.
  • ExportActionRetryReferenceAttribute This indicates that at least one reference attribute couldn't be written, but all non-reference attributes succeeded. It tells the sync engine that the object should be retried in the next export pass.

Import errors, fatal

There are two import errors that are supposed to only be used in delta import and to indicate that the delta change log is broken. Using one of these would be similar to an exception and would stop the sync engine from trying to continue delta import. These errors were initially introduced because there is one LDAP server (not naming any names here) that under load would corrupt its own delta change log. The server would then return these particular errors back on an object when trying to get the delta change. The expectation is that a full import is needed to get a new watermark so the bad section in the delta change log can be skipped.

  • ImportErrorParseError
  • ImportErrorReadError

Import errors, object-level

An error on an object-level is also known as a discovery error.

This list can be found on MSDN

In addition, there are also two custom errors that can be used. These work like the corresponding export error.

  • ImportErrorCustomContinueRun
  • ImportErrorCustomStopRun

When an error is returned on an object during import, it also implies a few other things to the sync engine.

  • During full import, object obsoletion should not occur at the end of the import.
  • During delta import, the watermark should not be preserved beyond the object with an error.

Watermarks

An error during delta import needs some additional explanation.

To understand the scenario, look at this picture.

Watermark processing

Watermark processing

During import, page 1 is read and watermark A is returned to the sync engine. The connector then reads page 2 from watermark A, but in it there is a problem with an object and a discovery error is returned on the object. The connector returns watermark B to the sync engine. Then the connector reads page 3 and is given watermark B from the sync engine to continue from, it is successful, and returns watermark C to the sync engine.

But, when the delta import operation has finished, the sync engine commits watermark A to the database. When the next delta import run occurs, it will again try page 2, fail, and continue with page 3 and the new page 4. This allows it to be able to continue to process new changes in the target directory. If this continues without the admin taking any interaction, the delta import process gets longer and longer over time. If the target directory is one where the delta change log is pruned over time, then delta import stops working when that happens and watermark A is no longer valid.

The most likely solution to the problem is to run a full import. After the full import has completed successfully, watermark C is committed to the database.