More
Errors
Rivet provides robust error handling with security built in by default. Errors are handled differently based on whether they should be exposed to clients or kept private.
There are two types of errors:
- UserError: Thrown from actors and safely returned to clients with full details
- Internal errors: All other errors that are converted to a generic error message for security
Throwing and Catching Errors
UserError lets you throw custom errors that will be safely returned to the client.
Throw a UserError with just a message:
import { actor, UserError } from "rivetkit";
const user = actor({
state: { username: "" },
actions: {
updateUsername: (c, username: string) => {
// Validate username
if (username.length > 32) {
throw new UserError("Username is too long");
}
// Update username
c.state.username = username;
}
}
});
import { actor, setup } from "rivetkit";
import { createClient, ActorError } from "rivetkit/client";
const user = actor({
state: { username: "" },
actions: {
updateUsername: (c, username: string) => {
if (username.length > 32) throw new Error("Username is too long");
c.state.username = username;
}
}
});
const registry = setup({ use: { user } });
const client = createClient<typeof registry>("http://localhost:6420");
const conn = client.user.getOrCreate([]).connect();
try {
await conn.updateUsername("extremely_long_username_that_exceeds_the_limit");
} catch (error) {
if (error instanceof ActorError) {
console.log(error.message); // "Username is too long"
}
}
import { actor, setup } from "rivetkit";
import { createClient, ActorError } from "rivetkit/client";
const user = actor({
state: { username: "" },
actions: {
updateUsername: (c, username: string) => {
if (username.length > 32) throw new Error("Username is too long");
c.state.username = username;
}
}
});
const registry = setup({ use: { user } });
const client = createClient<typeof registry>("http://localhost:6420");
const userActor = client.user.getOrCreate([]);
try {
await userActor.updateUsername("extremely_long_username_that_exceeds_the_limit");
} catch (error) {
if (error instanceof ActorError) {
console.log(error.message); // "Username is too long"
}
}
Error Codes
Use error codes for explicit error matching in try-catch blocks:
import { actor, UserError } from "rivetkit";
const user = actor({
state: { username: "" },
actions: {
updateUsername: (c, username: string) => {
if (username.length < 3) {
throw new UserError("Username is too short", {
code: "username_too_short"
});
}
if (username.length > 32) {
throw new UserError("Username is too long", {
code: "username_too_long"
});
}
// Update username
c.state.username =