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 toError method
..line
is set toError line
..code
is set toError 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 anError
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 outertry
block, or if there is no outertry
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
).