Lodash - error handling

About

js.component provides an integrated error handling framework that is consistent throughout all functions in the component. You must be ready to handle errors generated by the component, but otherwise use of the error framework is completely opt-in.

NOTE

You really, really will want to use js.component’s error handling framework. Once you start using it, you will wonder how you ever lived without it. 😁

Handling thrown errors

When errors occur within js.component, an Error object is thrown, meaning it is propagated to the error framework. It is up to you to decide how to handle the error. You can either:

  • Catch the error with catch; or
  • Let it bubble up to the uncaught error handler.

Catching errors

To catch an error, you enclose a block of code that might cause errors with If (_.try())/End if, which creates an isolated error context. You then use one or more _.catch() blocks to handle the errors, and after that call _.endTry() to pop the error context.

Here is a simple example:

// `If` is not necessary, but clearly shows the scope of the error context
If (_.try())
  var $object: Object

  // This will throw a SyntaxError because the JSON is malformed
  $object:=_.parseJSON("{ invalid JSON }")

  // catch() with no parameters catches all errors
  If (_.catch())
    // Production code would probably do something more useful here
    _.inspect(_.caught)
  End if

  _.endTry()
End if

There is much more to it. For details see the API documentation and the error handling section of the video training.

IMPORTANT

In order to catch errors in your own code, you must call _.setHostOnErrCall().

Uncaught errors

Errors that are not caught are passed to the uncaught error handler. js.component provides a default handler that displays the error in an alert. This is useful during development (unless the code is running on Server), but obviously not something you want end users to see in production. So on Server and in a production environment you will want override the default handler with your own by calling _.setUncaughtErrorHandle().

API

.catch()

.catch({ predicate : 4D.Class | Text | Number }) : Boolean

Catches errors that were thrown in the current try block and puts them in the _.caught collection. predicate can be:

  • Omitted: catches all errors.

  • A class: catches errors that are instances of that class.

  • A string: catches errors whose .message property matches the string, using normal 4D = string comparison (thus wildcards are supported), or if predicate begins and ends with /, it is treated as a regular expression.

  • A number: catches errors whose .error property matches the number.

Multiple catch() blocks can be used in a single try block. If an error is caught by more than one catch() block, it is only caught by the first one.

Any errors that are not caught by a catch() block are passed to the next outer try block, or if there are no more outer try blocks, to the uncaught error handler.

If _.catch() is called with no matching _.try() call, a SyntaxError is immediately thrown to the uncaught error handler.


.caught

.caught : Collection

The collection of errors caught by the last _.catch() block. This property is read-only and only valid inside a catch() block.


.clearLastUncaughtError()

.clearLastUncaughtError()

Clears the last uncaught error. If you set your own uncaught error handler, you should call this after handling the error.


.endTry()

.endTry({ value : any }) : any

Pops the current error context, restores the previous error handler and .caught, and returns value. This function must be called at the end of a try block.

If called with no matching _.try(), it immediately throws a SyntaxError to the uncaught error handler.

If you need to return early from within a try block, you must do so like this:

Function isSomething() : Boolean
  If (_.try())
    // Do something
    var $result : Object

    $result:=This.doSomething()

    // No error but we want to return early
    If ($result=Null)
      // You MUST call _.endTry() before returning
      return _.endTry(False)
    End if

    // Do something else

    If (_.catch())
      // Handle errors
    End if

    _.endTry()
    return True
  End if

.error()

.error() : Boolean

Returns true if an error was thrown in the current try block or if an uncaught error was thrown.


.errors

.errors : Collection

The collection of errors thrown in the current try block. This property is read-only and only valid inside a try block.


.lastError

.lastError : Object

The last error that was thrown, or null if no error has been thrown within the current try block. This property is read-only.


.lastUncaughtError

.lastUncaughtError : Object
.lastUncaughtError:= _ : Null

The last uncaught error that was thrown. This property is read-only.


.makeErrorConfig()

.makeErrorConfig({ message : Text { ; errorCode : Integer { ; options : Object }}}) : Object

Creates an error configuration object that can be passed to an error constructor.

If the current error handler (according to Method called on error) is in the call chain, this function assumes it is being called as a result of a 4D error, and an object is constructed and returned as follows:

  • Any passed parameters are ignored.

  • GET LAST ERROR STACK is used to get all of the 4D error information.

  • .message is set to the concatenation of the 4D error messages in the error stack.

  • .error is set to the 4D error code of the first error in the error stack.

  • .method is set to Error method.

  • .line is set to Error line.

  • .code is set to Error formula.

  • .stack is set the call chain, trimmed to the stack frame just before the error handler.

  • .options is set to options.

If the current error handler is not in the call chain, this function assumes an error was thrown directly and an object is constructed and returned as follows:

  • .message is set to message.

  • .error is set to errorCode.

  • .stack is set to the call chain trimmed to the stack frame that either constructed an Error or called _.throw().

  • .method is set to the name of the method/function at the top of the stack.

  • .line is set to the line number of the method/function at the top of the stack.

  • .code is set to "".

  • .options is set to options.


.maxErrorStackDepth

.maxErrorStackDepth : Integer
.maxErrorStackDepth:= depth : Integer

By default, the list of errors within a try block is limited to 7, with least recent errors being discarded once the limit is reached.

You can change this limit by setting this property. depth < 1 is pinned to 1.


.setHostOnErrCall()

.setHostOnErrCall(func : 4D.Function)

Sets the function to be called when js.component needs to call ON ERR CALL in the host db. The function is called with the name of the error handler method.

Because the host db maintains a separate error handler method from the component, js.component needs to synchronize its error handler method with the host db. You enable this synchronization by calling this function.

IMPORTANT

Unless you have some special needs, you should always call this function as early as possible in startup as follows:

_.setHostOnErrCall(Formula(ON ERR CALL($1)))

.setUncaughtErrorHandler()

.setUncaughtErrorHandler({ func : 4D.Function }) : 4D.Function

Sets the function that will be called when an uncaught error is thrown. The function is called with the error object as its only parameter. The previous uncaught error handler is returned.

If func is omitted or null, the default uncaught error handler is restored.


.throw()

.throw(message : Text { ; errorCode : Integer { ; options : Object }}) : cs.js.Error
.throw(error : Error) : Error

In the first form, this function constructs and returns an Error whose properties are set from _.makeErrorConfig(message; errorCode; options).

In the second form, error is thrown.

What happens with the thrown error depends on the current error context:

  • If you are not within a try block, the error is passed to the uncaught error handler.

  • If you are within a try block, the error is added to the .errors collection.

  • If you are within a catch block, the error is rethrown to the next outer try block, or if there is no outer try block, it is passed to the uncaught error handler.


.try()

.try() : True

Creates a new, isolated error context (a try block) and returns true, which allows you to use If (_.try()) to visually indicate the beginning and end of the try block.

_.try() does a few things:

  • Pushes jk std error handler onto the error handler stack.

  • Pushes a new error context onto the front of the error context stack. .errors and .caught are set to an empty collection.

  • Returns true.

For an example, see Catching errors above.

Constants

jk std error handler

jk std error handler : Text

The name of the standard error handler used by js.component (js_errorHandler).

Last Updated:
Contributors: Aparajita