In addition to declaring an output type on your TypeScript function, you can also declare an error type. This can be particularly useful for propagating and handling errors in the context of queries.
You can define an error type using the FunctionsError
type exported from @foundry/functions-api
. It takes two type parameters; a string name and an optional type that defaults to an empty object. Any valid output type for a function may be used as an error type, including objects and object sets.
You can union multiple FunctionsError
types together to define a set of possible errors for your function. For example, you could define the following error type for a function that gets an employee's teammates:
Copied!1 2 3 4 5 6
import { FunctionsError } from "@foundry/functions-api"; import { Employee } from "@foundry/ontology-api"; type GetTeammatesError = | FunctionsError<"EmployeeNotFoundForId", string> | FunctionsError<"MultipleEmployeesFoundForId", { employees: Employee[], employeeId: string }>
To declare an error type on a TypeScript function, you can use the FunctionsResult
type exported from @foundry/functions-api
. It takes two type parameters; an output type and an error type.
Using the GetTeammatesError
example from the previous section, you can declare the error type on a function like so:
Copied!1 2 3 4 5 6 7 8 9 10 11
import { Function, FunctionsError, FunctionsResult } from "@foundry/functions-api"; import { Employee } from "@foundry/ontology-api"; type GetTeammatesError = | FunctionsError<"EmployeeNotFoundForId", string> | FunctionsError<"MultipleEmployeesFoundForId", { employees: Employee[], employeeId: string }> @Function() public getTeammates(employeeId: string): FunctionsResult<Employee[], GetTeammatesError> { ... }
Note that by default the FunctionsResult
type includes a few errors that can be returned by the TypeScript function runtime infrastructure:
FunctionsTypeScriptExecutorService:CpuTimeoutError
: Returned when the function exceeds the CPU time limit.FunctionsTypeScriptExecutorService:WallTimeoutError
: Returned when the function exceeds the wall time limit.FunctionsTypeScriptExecutorService:OutOfMemoryError
: Returned when the function exceeds the memory limit.FunctionsTypeScriptExecutorService:RuntimeError
: Returned when the function encounters some other runtime error.To return outputs and errors, you can use the FunctionsResult.ok
and FunctionsResult.err
methods exported from @foundry/functions-api
:
FunctionsResult.ok
: Takes a single output value as its argument.FunctionsResult.err
: Takes an error name and value as its arguments.Using the getTeammates
example from the previous section, you can return outputs and errors like so:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
import { Function, FunctionsError, FunctionsResult } from "@foundry/functions-api"; import { Employee } from "@foundry/ontology-api"; type GetTeammatesError = | FunctionsError<"EmployeeNotFoundForId", string> | FunctionsError<"MultipleEmployeesFoundForId", { employees: Employee[], employeeId: string }> @Function() public getTeammates(employeeId: string): FunctionsResult<Employee[], GetTeammatesError> { const employees = await Objects.search().employee([employeeId]).allAsync(); if (employees.length === 0) { return FunctionsResult.err("EmployeeNotFoundForId", employeeId); } if (employees.length > 1) { return FunctionsResult.err("MultipleEmployeesFoundForId", { employees, employeeId }); } const employee = employees[0]; const teammates = await employee.teammates.allAsync(); return FunctionsResult.ok(teammates); }
When a function with an error type is called as a query from another repository, it returns a Result
type response, which can be an ok
or err
result.
You can use the isOk
or isErr
type guards exported from @foundry/functions-api
to differentiate between the two possible results. For instance, call the getTeammates
example from the previous section, assuming you also published it as a query, and handle the response like so:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
import { Function, isOk } from "@foundry/function-api"; import { getTeammates } from "@foundry/ontology-api/queries"; @Function() public async myFunction(employeeId: string): Promise<string> { const result = await getTeammates({ employeeId }); if (isOk(result)) { const teammates = result.value; // Do something with "teammates" here ... } // You can inspect the "name" field to case on each error by name and use the "value" field to get the error value switch (result.error.name) { case "EmployeeNotFoundForId": ... case "MultipleEmployeesFoundForId": ... case "FunctionsTypescriptExecutorService:OutOfMemoryError": ... ... } }