Skip to main content

Getting Started with Optic

To Handle Document Update Errors

[v11.2.0 and up]

You can include an error-handling function to continue an update despite errors and to report those errors.

The Integration Department has completed their collection of R&D employees to let go. As before, we have added these employees to the Attrition collection and updated the Attrition Department description.

Also as before, we want to update some individual document properties with the Status of Terminated and the new property TerminationDate using the same update code.

But using the same code will not work: some of the employee documents in the collection already have the new property, so trying to add it again will cause an error, stopping the update process.

We want the process to continue, updating all possible documents and reporting errors for the document updates that fail.

An Optic update like this one completes the update, skipping the documents that fail and adding an error column to the response rows:

declareUpdate();
const op = require('/MarkLogic/optic');
op.fromDocUris(cts.collectionQuery('https://example.com/content/department/Attrition'))
  .joinDocCols(null, op.fragmentIdCol('fragmentId'))
  .patch(
    op.col('doc'),
    op.patchBuilder('/')
      .replaceValue('Status', "Terminated")
      .insertAfter('HiredDate', xdmp.toJSON({'TerminationDate': fn.currentDate()}).root.TerminationDate)
  )
  .write()
  .onError('continue')
  .result();

We used this update as before. It is the same except that we added onError() and replaced execute() with result() so that we can see the error column.

  • The Operator Function onError() with the parameter continue continues processing the update after encountering an error, adding the new column sys.errors to the resulting rows.

  • You can use only one onError() function per update.

  • onError() must be followed directly by either execute() or result().

  • onError() catches only runtime errors, not pre-runtime errors like these:

    • Trying to access a non-existent view.

    • Trying to access a non-existent column.

    • Trying to access a non-existent document.

    • Syntax errors on your SPARQL or SQL strings.

    • Optic Search errors.

  • Use onError('fail') to fail as soon as an error is encountered. This option yields the same results as not using onError() at all.

Here is one of the rows with its error column populated because this Marketing employee document already had the TerminationDate property:

{
 "uri": "/data/employees/b0d5a15e-b5ce-4138-9a59-f46e08119bc4.json", 
 "doc": {
  "GUID": "b0d5a15e-b5ce-4138-9a59-f46e08119bc4", 
  "Gender": "male", 
  "Title": "Mr.", 
  "GivenName": "Ralph", 
  "MiddleInitial": "M", 
  "Surname": "Deweese", 
  "StreetAddress": "2031 O Conner Street", 
  "City": "Gulfport", 
  "State": "MS", 
  "ZipCode": "39507", 
  "Country": "US", 
  "EmailAddress": "RalphMDeweese@rhyta.com", 
  "TelephoneNumber": "228-850-3365", 
  "TelephoneCountryCode": "1", 
  "Birthday": "11/25/62", 
  "NationalID": "428-08-3456", 
  "BaseSalary": "75054", 
  "Bonus": "7505", 
  "Department": "Marketing", 
  "Status": "Terminated", 
  "ManagerGUID": "d0862e5d-5be6-473b-a500-3e3a852b2bb8", 
  "point": {
   "lat": 30.372732, 
   "long": -88.999739
  }, 
  "HiredDate": "2020-03-18"
  "TerminationDate": "2024-03-2024"
 }, 
 "sys.errors": {
  "data": [
  ],
  "message": "Object nodes cannot have two children with the same name",
  "name": "XDMP-CHILDDUPNAME",
  "documentUri": "/data/employees/b0d5a15e-b5ce-4138-9a59-f46e08119bc4.json",
  "uri": null,
  "operatorId": "2687000105340244565"
 }
}
  • Use the 'errosOnly' option of result() (for example, result(null, null, ['errorsOnly'])) to return only rows containing documents whose update fail.

  • To change the default error column name, sys.errors, to something else, like MyErrors, use onError('continue',op.col('MyErrors')).