# Data Process Error Handling Tips ## When ```handleError()``` Would be Called In every LOC data process' generic/aggregator logics, there is a ```handleError``` function: ```javascript async function handleError(ctx, error) { ctx.agents.logging.error(error.message); // log the error } ``` :::info Use ```export async function handleError``` if you are using ++[LOC CLI](https://hackmd.io/4LIsNIuWQnuR70JMeuBAEA)++. ::: If any error was thrown in a logic, its ```handleError()``` would be called. More importantly, *all* ```handleError()``` of the subsequent logics - including the aggregator - will also be called with the same error passed into these functions. (In other words, the data process task was *failed*.) For example, in the following table, an error occurred in generic logic #3. All ```handleError()``` from generic logic #3 until the aggregator logic will be called (with the error from #3 pass down all the way): | Logics | Error occurred? | Called function | | ---------- | --------------- | ------------------- | | generic #1 | No | ```run()``` | | generic #2 | No | ```run()``` | | generic #3 | Yes | ```handleError()``` | | generic #4 | N/A | ```handleError()``` | | generic #5 | N/A | ```handleError()``` | | aggregator | N/A | ```handleError()``` | ## Return Error Result in Aggregator Under normal circumstances, the aggregator wouldn't be able to produce any meaningful result whenever one of its logics fail. However, we can still return the error with ```ctx.agents.result```: ```javascript // error handling in aggregator async function handleError(ctx, error) { ctx.agents.result.finalize({ error: error.message, // return the error as part of the result taskId: ctx.task.taskId, }); } ``` This allows users to see some useful information in the API route response or logging, etc. Even though the error message is null due to some reason, the ```error``` field still indicates that some error had occurred. ## Use ```try/catch``` to Intercept Errors Sometimes you do hope other logics can keep running even though some logics may encounter (expected) errors. You can use [**try/catch**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling) to handle errors yourself and avoid task failure: ```javascript // logic in aggregator async function run(ctx) { try { // something that might went wrong } catch (error) { // if something went wrong, get an error // log the error ctx.agents.logging.error(error.message); // store the error in session store await ctx.agents.sessionStorage.putString("logic_01_error", error.message); } finally { // do things that need to be done // whether there are errors or not } } ``` And you can store error in the same way in the 2^nd^ logic (as ```logic_02_error```), 3^rd^ logic (as ```logic_03_error```), and so on. :::info You can use multiple ```try/catch``` blocks in any logics to intercept different errors. ::: Finally, in the aggregator, you can check each of the errors from all logics: ```javascript async function run(ctx) { // read potential errors from all logics const logic_01_error = await ctx.agents.sessionStorage.get("logic_01_error"); const logic_02_error = await ctx.agents.sessionStorage.get("logic_02_error"); ... let status = 200; // check if there are errors; if so, set our custom status as 500 if (logic_01_error & logic_02_error ...) { status = 500; } ctx.agents.result.finalize({ status: status, taskId: ctx.task.taskId, error: { // if a field value is null, it means no error in that logic logic_01_error: logic_01_error, logic_02_error: logic_02_error, ... } }); } ``` ## Throwing Error However, there may be times that some errors caught by ```try/catch``` are simply too serious to allow the data process to continue. For situations like this, you can deliberately **throw** an error to trigger the ```handleError()``` mechanism: ```javascript async function run(ctx) { try { ... } catch (error) { if (error instanceof TypeError) { // if error is a TypeError hrow new TypeError("There is a TypeError...") } else if (error.message != "xxx") { throw new Error("There is some error...") } } finally { // do things that need to be done // whether there are errors or not } } ``` Since we've thrown unhandled errors, the data process' ```handleError()``` will take over and do the rest. :::info **Error** is the most generic error type; see ++[Error types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#error_types)++ for possible JavaScript error types. You can also define ++[custom error types](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Error#custom_error_types)++. ::: ###### tags: `LOC Studio` `LOC CLI`