Recover From Errors and Failures
Handle typed errors, and react to load failures and stuck tracks.
Hoshimi throws typed errors and emits events for playback failures. Handle both to keep a session resilient.
Typed error handling
Every failure is an instance of a specific error class, so instanceof routes each to the right recovery.
import {
,
,
,
,
,
,
,
,
,
} from 'hoshimi';
try {
// Any Hoshimi operation that may fail
} catch () {
if ( instanceof ) {
.('Invalid options:', .);
} else if ( instanceof ) {
.('Manager state error:', .);
} else if ( instanceof ) {
.('Node connection error:', .);
} else if ( instanceof ) {
.('No node available:', .);
} else if ( instanceof ) {
.('Queue state error:', .);
} else if ( instanceof ) {
.('Playback error:', .);
} else if ( instanceof ) {
.('Track resolution failed:', .);
} else if ( instanceof ) {
.('Lavalink REST error:', .);
} else if ( instanceof ) {
.('Storage adapter error:', .);
} else {
.('Unknown error:', );
}
}Error categories
| Error Type | Cause | Recovery |
|---|---|---|
| OptionError | Invalid configuration | Fix options, restart |
| ManagerError | Invalid manager state | Check manager initialization |
| NodeError | Node connection/status | Retry, fallback to another node |
| PlayerError | Invalid player operation | Validate player state |
| ResolveError | Track lookup failed | Try a different search query |
| RestError | Lavalink HTTP error | Retry with backoff |
| StorageError | Adapter operation failed | Check storage backend |
| NodeManagerError | No connected node to pick | Wait for a node, or add one |
| QueueError | Queue holds something that is not a track | Inspect what was pushed into it |
| MergeError | A required manager option is missing | Fix the options object |
RestError carries the Lavalink response: status, error, path and trace alongside message. NodeError names the node in error.name, so logs point at the right one in a multi-node fleet.
Load failures and stuck tracks
A track can fail to load, or stall mid-playback. Let Hoshimi react automatically with onError, and observe it with the trackStuck event.
const = ({
,
: [{ : 'localhost', : 2333, : 'youshallnotpass' }],
: {
: {
: true, // stop playback on a track error instead of stalling
},
},
});
.('trackStuck', (, ) => {
.(`Stuck: ${?.. ?? 'unknown'} in ${.}`);
});onError.autoDestroy tears the player down instead (it takes precedence over autoStop). For disconnects, onDisconnect offers autoReconnect, autoDestroy and autoQueue.
Recovery checklist
- Before commands: check
manager.isUsable()for a quick health gate. - Before player operations: verify voice channel access and player existence.
- Queue operations: guard with
queue.isEmpty()before shifting/accessing. - Session persistence: save player/queue state after successful updates — see Resume sessions after a restart.
- Cleanup: on
queueEndandplayerDestroy, clear transient storage (lyrics ids, message refs).