Error Handling
During one message exchange, a lot of things can go wrong, including:
- Some error happens before the message can be sent
- For example, the other side is already closed
- The receiving side throws an exception while processing the message
- The receiving side doesn't respond
This is why the interface methods are required
to return a WorkexPromise<T>
type, which is a Promise<WorkexResult<T>>
.
The result type is powered by pure,
which is a type-only implementation of Rust's Result
type.
The send side can check the result like:
const client = ... // this is the client object
const result = await client.doSomething();
// result is WorkexResult<T>
if (result.err) {
// handle error
if (result.err.type === "Catch") {
const message = result.err.message;
// message can be a few things:
// - "Terminated" if the worker is terminated
// - "Timeout" if the worker doesn't respond, and timeout is set
// in the options
// - Best-effort string representation of the error thrown on the other side
console.error(message);
return;
}
if (result.err.type === "Internal") {
// this is an internal error, which should not happen
console.error("Internal error", result.err.message);
return;
}
}
// result.val is inferred to be T
console.log(result.val);
As you noticed, if the remote side throws an exception, it will be caught and converted to a string to send to the original side. This ensures maximum compatibility with the message transport method (Worker, WebSocket, network call...).
This means if you need to get structured error data from the other side, throwing exception is not the best option.
You can consider using the Result
type from pure
yourself:
// Void is the Result type where `void` is returned on success
import type { Void } from "@pistonite/pure/result";
import type { WorkexPromise } from "./workex";
import type { MyError } from "somewhere/my_error";
export interface Foo {
doSomethingCanFail(): WorkexPromise<Void<MyError>>;
}
Now you can chain the error handling like this:
const client = ... // this is the client object
const messageResult = await client.doSomething();
// result is WorkexResult<T>
if (messageResult.err) {
// handle the error like above
...
return;
}
const result = messageResult.val;
if (result.err) {
// handle your error
console.error(result.err);
return;
}
// success...
Check out the documentation for pure on JSR for more into!