Handling errors
Jstz processes calls to smart functions as an atomic unit that succeeds entirely or fails entirely. Failed calls to smart functions immediately revert all calls that came from that transaction and any side effects they may have had. For example, assume that a user calls smart function A, which causes function A to call smart function B. If smart function B throws an uncaught error, all of the calls are reverted, including the original call to function A.
When a chain of calls to smart functions fails in this way, these things happen:
- The storage of each smart function in the chain is set back to what it was before the initial request, like a database rollback.
- The XTZ balance of each smart function is restored to what it was before the initial request.
- Any further requests generated by the smart functions are cancelled.
Catching errors
You can catch errors in smart functions just like in ordinary JavaScript/TypeScript applications, including with try/catch blocks and the .catch()
function on promises, as in this example:
// Assume that this smart function always throws an exception
const alwaysFails = "KT1VzoTKPPX7ZnPrCDcj9pTUK4dTs5A9k1zv";
const handler = async (request: Request): Promise<Response> => {
const requester = request.headers.get("Referer") as Address;
console.log(`${requester} calls.`);
// Standard JavaScript try/catch
try {
await SmartFunction.call(
new Request(`jstz://${alwaysFails}`, {
method: "POST",
body: "",
}),
);
} catch (e) {
console.log(`Caught exception: ${e}`);
}
// .catch function on promise
await SmartFunction.call(
new Request(`jstz://${alwaysFails}`, {
method: "POST",
body: "",
}),
).catch((e) => console.log(`Caught exception: ${e}`));
return new Response("OK", {
headers: {
"Content-Type": "text/utf-8",
},
});
};
export default handler;
If you call this smart function, the smart function processes the request normally, catches the errors, and returns the response to the caller.
Throwing exceptions
Smart functions can throw exceptions in the usual ways that JavaScript/TypeScript applications throw exceptions, including by using the throw
keyword and by failing to catch exceptions that commands throw.
They also throw exceptions when they do things that Jstz does not allow them to do, such as sending more tez than their current balance holds or calling a smart function address that does not exist.