Disclaimer
I'm not sure if this can be considered an expected behavior or not, but since it took me a while to understand what was happening, it might help someone with the same scenario.
Description
There are two ways to import SenderError in the TypeScript SDK: from the root 'spacetimedb' package or from 'spacetimedb/server'.
If a reducer throws a SenderError imported from the root package, the database runtime fails to recognize it as a standard sender error. Instead, it treats it as an unhandled exception, resulting in a database PANIC (internal error) rather than a clean, handled reducer failure.
Reproducible Example
import { SenderError as SenderErrorRoot } from 'spacetimedb';
import { SenderError } from 'spacetimedb/server';
// logs: ERROR: regular_error: sender_error
export const regularError = spacetimedb.reducer({}, (ctx, args) => {
throw new SenderError('sender_error');
});
// This causes a database panic/internal error
// logs: PANIC: internal_error src/reducers/example.ts:14: Uncaught sender_error_root
export const internalError = spacetimedb.reducer({}, (ctx, args) => {
throw new SenderErrorRoot('sender_error_root');
});
Disclaimer
I'm not sure if this can be considered an expected behavior or not, but since it took me a while to understand what was happening, it might help someone with the same scenario.
Description
There are two ways to import
SenderErrorin the TypeScript SDK: from the root'spacetimedb'package or from'spacetimedb/server'.If a reducer throws a
SenderErrorimported from the root package, the database runtime fails to recognize it as a standard sender error. Instead, it treats it as an unhandled exception, resulting in a databasePANIC(internal error) rather than a clean, handled reducer failure.Reproducible Example