Skip to content

Handling Errors

All Bridge API methods can throw errors. VibeDepot uses a structured error system called DxError that provides an error code, a message, and a developer-friendly suggestion.

When a Bridge API call fails, the thrown error has these properties:

{
code: 'MISSING_API_KEY', // Machine-readable error code
message: 'No API key available...', // Human-readable description
suggestion: 'Open Settings and...' // Guidance for fixing the issue
}

Always wrap Bridge API calls in try/catch:

try {
const response = await window.vibeDepot.ai.callAI({
messages: [{ role: 'user', content: 'Hello!' }]
});
displayResult(response.content);
} catch (err) {
displayError(err.message);
console.error(err.code, err.suggestion);
}
CodeWhen It FiresTypical Suggestion
PERMISSION_DENIEDApp lacks the required permissionAdd the permission to manifest.json
MISSING_API_KEYNo API key configured for any supported providerOpen Settings and add an API key
INVALID_PARAMSParameters failed Zod validationCheck the Bridge API docs for correct format
AI_PROVIDER_ERRORThe AI provider API returned an errorCheck API key validity and credits
STORAGE_ERRORKV storage operation failedCheck storage permissions
DB_ERRORSQLite operation failedCheck SQL syntax and storage.db permission
UNKNOWNUnexpected errorReport the issue
try {
await window.vibeDepot.ai.callAI({ messages: [...] });
} catch (err) {
if (err.code === 'PERMISSION_DENIED') {
showBanner('This feature requires additional permissions. ' + err.suggestion);
return;
}
throw err; // Re-throw unexpected errors
}
try {
await window.vibeDepot.ai.callAI({ messages: [...] });
} catch (err) {
if (err.code === 'MISSING_API_KEY') {
showSetupPrompt('Please configure an API key in VibeDepot Settings to use this app.');
return;
}
throw err;
}

These include rate limits, invalid keys, insufficient credits, and model errors:

try {
await window.vibeDepot.ai.callAI({ messages: [...] });
} catch (err) {
if (err.code === 'AI_PROVIDER_ERROR') {
// err.message includes the provider name and original error
showError('AI service error. Try again in a moment.');
return;
}
throw err;
}
try {
await window.vibeDepot.db.run('INSERT INTO notes (title) VALUES (?)', ['Hello']);
} catch (err) {
if (err.code === 'DB_ERROR') {
// Could be invalid SQL, blocked statement, or SQLite error
console.error('Database error:', err.message);
return;
}
throw err;
}

Streaming calls (streamAI) can also throw. The error fires when the stream encounters a problem:

try {
await window.vibeDepot.ai.streamAI(
{ messages: [{ role: 'user', content: 'Hello!' }] },
(chunk) => {
output.textContent += chunk;
}
);
} catch (err) {
// Stream failed — could be mid-stream
output.textContent += '\n\n[Stream error: ' + err.message + ']';
}

A pattern for showing errors to users:

function showError(err) {
const errorDiv = document.getElementById('error');
if (err.code === 'MISSING_API_KEY') {
errorDiv.textContent = 'Please add an API key in VibeDepot Settings.';
} else if (err.code === 'AI_PROVIDER_ERROR') {
errorDiv.textContent = 'The AI service returned an error. Please try again.';
} else if (err.code === 'PERMISSION_DENIED') {
errorDiv.textContent = 'This app needs additional permissions to work.';
} else {
errorDiv.textContent = 'Something went wrong. Please try again.';
}
errorDiv.style.display = 'block';
}

Don’t expose raw error messages or suggestions to end users — those are for developers. Show friendly messages instead.