From 882b3fa6fdb9aee47d14ce67c8b0d1cca8a7efe3 Mon Sep 17 00:00:00 2001
From: Sami Vaarala duktape.h
, e.g. DUK_ERR_TYPE_ERROR
flags. Negative error values are used in the Duktape/C API as a
shorthand to automatically throw an error.
Error handling in the Duktape API is similar to how Ecmascript handles
+errors: errors are thrown either explicitly or implicitly, then caught and
+handled. However, instead of a try-catch statement application code uses
+protected
+Duktape API calls to establish points in C code where errors can be caught
+and handled.
+An uncaught error causes the fatal error handler to be called, which is
+considered an unrecoverable situation and should ordinarily be avoided
+(see Error, fatal, and panic).
To avoid fatal errors, typical application code should establish an error +catch point before making other Duktape API calls. This is done using +protected Duktape API calls, for example:
+An example of the first technique:
++/* Use duk_peval() variant to evaluate a file so that script errors are + * handled safely. Both syntax errors and runtime errors are caught. + */ + +if (duk_peval_file(ctx, "myscript.js") != 0) { + /* Use duk_safe_to_string() to convert error into string. This API + * call is guaranteed not to throw an error during the coercion. + */ + printf("Script error: %s\n", duk_safe_to_string(ctx, -1)); +} +duk_pop(ctx); ++ +
An example of the second technique:
++/* Use duk_safe_call() to wrap all unsafe code into a separate C function. + * This approach has the advantage of covering all API calls automatically + * but is a bit more verbose. + */ + +static duk_ret_t unsafe_code(duk_context *ctx) { + /* Here we can use unprotected calls freely. */ + duk_eval_file_noresult(ctx, "myscript.js"); + + /* ... */ + + return 0; /* success return, no return value */ +} + +/* elsewhere: */ + +if (duk_safe_call(ctx, unsafe_code, 0 /*nargs*/, 1 /*nrets */) != 0) { + /* The 'nrets' argument should be at least 1 so that an error value + * is left on the stack if an error occurs. To avoid further errors, + * use duk_safe_to_string() for safe error printing. + */ + printf("Unexpected error: %s\n", duk_safe_to_string(ctx, -1)); +} +duk_pop(ctx); ++ +
Even within protected calls there are some rare cases, such as internal +errors, that will either cause a fatal error or propagate an error outwards +from a protected API call. These should only happen in abnormal conditions +and are not considered recoverable. To handle also these cases well, a +production quality application should always have a fatal error handler with +a reasonable strategy for dealing with fatal errors.
+ +Note that it may be fine for some applications to make API calls without +an error catcher and risk throwing uncaught errors. Even in this case there +should be a fatal error handler to easily detect and fix any remaining errors.
+ +An ordinary error is caused by a throw
statement,
a duk_throw()
API call (or similar), or by an internal,
recoverable Duktape error. Ordinary errors can be caught with a
try-catch
in Ecmascript code or e.g. duk_pcall()
+(see API calls tagged
+protected
)
in C code.
An uncaught error or an explicit call to duk_fatal()
causes