Skip to content

Commit d299ed7

Browse files
committed
feat: use Exception instances instead of strings in runNoThrow()
1 parent ad2947a commit d299ed7

File tree

5 files changed

+121
-7
lines changed

5 files changed

+121
-7
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,18 @@ if (result.outputs) {
124124
console.log("Success:", result.outputs);
125125
console.log("Task ID:", result.detail.taskId); // For tracking/debugging
126126
} else {
127-
console.log("Failed:", result.detail.error);
127+
console.log("Failed:", result.detail.error.message); // Error message
128128
console.log("Task ID:", result.detail.taskId); // Still available on failure
129+
console.log("Stack trace:", result.detail.error.stack); // Full stack trace
130+
131+
// Check specific error types
132+
if (result.detail.error instanceof WavespeedTimeoutException) {
133+
console.log("Request timed out");
134+
} else if (result.detail.error instanceof WavespeedConnectionException) {
135+
console.log("Connection failed");
136+
} else if (result.detail.error instanceof WavespeedPredictionException) {
137+
console.log("Prediction failed");
138+
}
129139
}
130140
```
131141

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/api/client.ts

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,68 @@ export interface RunOptions {
1414
maxRetries?: number; // Maximum task-level retries (overrides client setting)
1515
}
1616

17+
/**
18+
* Base exception class for WaveSpeed errors
19+
*/
20+
export class WavespeedException extends Error {
21+
constructor(
22+
message: string,
23+
public readonly taskId: string = 'unknown',
24+
public readonly model: string = ''
25+
) {
26+
super(message);
27+
this.name = 'WavespeedException';
28+
}
29+
}
30+
31+
/**
32+
* Timeout exception
33+
*/
34+
export class WavespeedTimeoutException extends WavespeedException {
35+
constructor(taskId: string, model: string, public readonly timeout: number) {
36+
super(`Prediction timed out after ${timeout} seconds`, taskId, model);
37+
this.name = 'WavespeedTimeoutException';
38+
}
39+
}
40+
41+
/**
42+
* Connection exception
43+
*/
44+
export class WavespeedConnectionException extends WavespeedException {
45+
constructor(taskId: string, model: string, details: string) {
46+
super(`Connection failed: ${details}`, taskId, model);
47+
this.name = 'WavespeedConnectionException';
48+
}
49+
}
50+
51+
/**
52+
* Prediction failed exception
53+
*/
54+
export class WavespeedPredictionException extends WavespeedException {
55+
constructor(taskId: string, model: string, errorMessage: string) {
56+
super(`Prediction failed: ${errorMessage}`, taskId, model);
57+
this.name = 'WavespeedPredictionException';
58+
}
59+
}
60+
61+
/**
62+
* Unknown exception
63+
*/
64+
export class WavespeedUnknownException extends WavespeedException {
65+
constructor(taskId: string, model: string, originalError: any) {
66+
super(String(originalError), taskId, model);
67+
this.name = 'WavespeedUnknownException';
68+
}
69+
}
70+
1771
/**
1872
* Detail information for runNoThrow result.
1973
*/
2074
export interface RunDetail {
2175
taskId: string; // Task ID for tracking and debugging
2276
status: 'completed' | 'failed'; // Task status
2377
model: string; // Model identifier
24-
error?: string; // Error message if failed
78+
error?: WavespeedException; // Exception instance if failed
2579
createdAt?: string; // Task creation timestamp
2680
}
2781

@@ -507,14 +561,14 @@ export class Client {
507561
const taskId = data.id || 'unknown';
508562

509563
if (status !== 'completed') {
510-
const error = data.error || 'Unknown error';
564+
const errorMsg = data.error || 'Unknown error';
511565
return {
512566
outputs: null,
513567
detail: {
514568
taskId,
515569
status: 'failed',
516570
model,
517-
error,
571+
error: new WavespeedPredictionException(taskId, model, errorMsg),
518572
createdAt: data.created_at
519573
}
520574
};
@@ -550,7 +604,7 @@ export class Client {
550604
taskId: 'unknown',
551605
status: 'failed',
552606
model,
553-
error: 'Invalid response from _submit'
607+
error: new WavespeedUnknownException('unknown', model, 'Invalid response from _submit')
554608
}
555609
};
556610

@@ -563,13 +617,28 @@ export class Client {
563617
const taskIdMatch = error.message?.match(/task_id: ([a-f0-9-]+)/);
564618
const taskId = taskIdMatch ? taskIdMatch[1] : 'unknown';
565619

620+
// Determine exception type based on error
621+
let exception: WavespeedException;
622+
const errorStr = error.toString().toLowerCase();
623+
624+
if (errorStr.includes('timeout') || errorStr.includes('timed out')) {
625+
exception = new WavespeedTimeoutException(taskId, model, timeout || 0);
626+
} else if (errorStr.includes('connection') || errorStr.includes('fetch') || error.name === 'AbortError' || error.name === 'TypeError') {
627+
exception = new WavespeedConnectionException(taskId, model, error.message || String(error));
628+
} else if (errorStr.includes('prediction failed')) {
629+
const errorMsg = error.message?.replace(/Prediction failed \(task_id: [a-f0-9-]+\): /, '') || 'Unknown error';
630+
exception = new WavespeedPredictionException(taskId, model, errorMsg);
631+
} else {
632+
exception = new WavespeedUnknownException(taskId, model, error);
633+
}
634+
566635
return {
567636
outputs: null,
568637
detail: {
569638
taskId,
570639
status: 'failed',
571640
model,
572-
error: error.message || String(error)
641+
error: exception
573642
}
574643
};
575644
}
@@ -589,7 +658,7 @@ export class Client {
589658
taskId: 'unknown',
590659
status: 'failed',
591660
model,
592-
error: `All ${taskRetries + 1} attempts failed`
661+
error: new WavespeedUnknownException('unknown', model, `All ${taskRetries + 1} attempts failed`)
593662
}
594663
};
595664
}

src/api/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,23 @@
2020

2121
import { Client } from './client';
2222
import type { RunOptions, RunDetail, RunNoThrowResult } from './client';
23+
import {
24+
WavespeedException,
25+
WavespeedTimeoutException,
26+
WavespeedConnectionException,
27+
WavespeedPredictionException,
28+
WavespeedUnknownException
29+
} from './client';
2330

2431
export { Client };
2532
export type { RunOptions, RunDetail, RunNoThrowResult };
33+
export {
34+
WavespeedException,
35+
WavespeedTimeoutException,
36+
WavespeedConnectionException,
37+
WavespeedPredictionException,
38+
WavespeedUnknownException
39+
};
2640

2741
// Default client instance
2842
let _defaultClient: Client | null = null;

src/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,23 @@ import './config';
2323
// Import API client
2424
import { Client, run, upload } from './api';
2525
import type { RunOptions, RunDetail, RunNoThrowResult } from './api/client';
26+
import {
27+
WavespeedException,
28+
WavespeedTimeoutException,
29+
WavespeedConnectionException,
30+
WavespeedPredictionException,
31+
WavespeedUnknownException
32+
} from './api';
2633

2734
export { version, Client, run, upload };
2835
export type { RunOptions, RunDetail, RunNoThrowResult };
36+
export {
37+
WavespeedException,
38+
WavespeedTimeoutException,
39+
WavespeedConnectionException,
40+
WavespeedPredictionException,
41+
WavespeedUnknownException
42+
};
2943

3044
// Default export (Client class)
3145
export default Client;

0 commit comments

Comments
 (0)