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 TypeError because we are assigning to the wrong type
$object:=7
// 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
.messageproperty 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
.errorproperty 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 STACKis used to get all of the 4D error information..messageis set to the concatenation of the 4D error messages in the error stack..erroris set to the 4D error code of the first error in the error stack..methodis set toError method..lineis set toError line..codeis set toError formula..stackis set the call chain, trimmed to the stack frame just before the error handler..optionsis 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:
.messageis set to message..erroris set to errorCode..stackis set to the call chain trimmed to the stack frame that either constructed anErroror called_.throw()..methodis set to the name of the method/function at the top of the stack..lineis set to the line number of the method/function at the top of the stack..codeis set to""..optionsis 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
tryblock, the error is passed to the uncaught error handler.If you are within a
tryblock, the error is added to the.errorscollection.If you are within a
catchblock, the error is rethrown to the next outertryblock, or if there is no outertryblock, 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 handleronto the error handler stack.Pushes a new error context onto the front of the error context stack.
.errorsand.caughtare 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).