Overview
TestDriver gives custom error classes with full debug information. The SDK exports them. You can use them for instanceof checks in your tests.
javascriptimport TestDriver, { ElementNotFoundError, AIError } from 'testdriverai';
ElementNotFoundError
TestDriver throws this when find() cannot find an element on the screen. It also throws this when you call click() or hover() on an element that TestDriver did not find.
javascripttry { await testdriver.find('nonexistent button').click(); } catch (error) { if (error instanceof ElementNotFoundError) { console.log(error.description); // "nonexistent button" console.log(error.screenshotPath); // path to debug screenshot console.log(error.pixelDiffPath); // path to pixel diff image } }
Properties
Enhanced Message
The error message is automatically enhanced with debugging information:
Element not found: "submit button" === Element Debug Info === Element: submit button Cache Hit: false Similarity: 0.23 Cache Strategy: pixel-diff Threshold: 0.05 AI Response Element: null
Stack Trace Cleaning
Stack traces are automatically cleaned to remove internal SDK frames (Element.*, sdk.js internals), showing only your test code for easier debugging.
AIError
Thrown when act() exhausts all retry attempts.
javascripttry { await testdriver.act('perform complex workflow', { tries: 3 }); } catch (error) { if (error instanceof AIError) { console.log(error.task); // "perform complex workflow" console.log(error.tries); // 3 console.log(error.duration); // 15234 (ms) console.log(error.cause); // underlying Error } }
Properties
Enhanced Message
AI failed: Element not found after 3 attempts === AI Execution Details === Task: perform complex workflow Tries: 3 / 3 Duration: 15234ms Cause: ElementNotFoundError: Element not found: "submit button"
Internal Error Classes
These errors are used internally by the agent and are not exported, but may appear as the cause of an AIError:
MatchError
Thrown when element matching fails (text, image, or assertion).
| Property | Type | Description |
|---|---|---|
fatal | boolean | If true, cannot be healed. Default: false |
attachScreenshot | boolean | Always true — a screenshot is attached to the error |
CommandError
Thrown for invalid arguments or unsupported operations.
| Property | Type | Description |
|---|---|---|
fatal | boolean | Always true |
attachScreenshot | boolean | Always false |
Soft Assert Mode
Inside act(), assertions run in soft assert mode. When an assertion fails, it returns the failure result instead of throwing, allowing the AI to process the failure and adjust its approach.
javascript// Inside act(), assertion failures don't throw await testdriver.act('verify the dashboard shows correct data', { tries: 3, }); // The AI can see assertion results and self-correct
This is automatic — you don't need to configure it. Regular assert() calls outside of act() will throw normally on failure.
Error Handling Patterns
Catching Specific Errors
javascriptimport TestDriver, { ElementNotFoundError, AIError } from 'testdriverai'; try { await testdriver.find('submit button').click(); } catch (error) { if (error instanceof ElementNotFoundError) { // Element wasn't found — check screenshot for debugging console.log('Debug screenshot:', error.screenshotPath); } else if (error instanceof AIError) { // AI exhausted retries console.log(`Failed after ${error.tries} tries in ${error.duration}ms`); } else { throw error; // Unexpected error } }
Using Debug Screenshots
javascripttry { const el = await testdriver.find('checkout button'); await el.click(); } catch (error) { if (error instanceof ElementNotFoundError) { // Screenshot of what the screen looked like console.log('Screen:', error.screenshotPath); // Pixel diff showing cache comparison console.log('Diff:', error.pixelDiffPath); // Full AI response metadata console.log('AI:', JSON.stringify(error.aiResponse, null, 2)); } }
Types
typescriptclass ElementNotFoundError extends Error { name: 'ElementNotFoundError'; description: string; screenshotPath: string | null; pixelDiffPath: string | null; cachedImagePath: string | null; aiResponse: Record<string, any> | null; timestamp: string; } class AIError extends Error { name: 'AIError'; task: string; tries: number; maxTries: number; duration: number; cause?: Error; timestamp: string; }


