refactor(new merge) (#369)
Co-authored-by: paisley <8197966+su8su@users.noreply.github.com> Co-authored-by: zuolingxuan <zuolingxuan@bytedance.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
e28eba01e1
commit
3d664c017a
102
src/lib/error-model.ts
Normal file
102
src/lib/error-model.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
export type AppErrorCode =
|
||||
| 'AUTH_INVALID'
|
||||
| 'TIMEOUT'
|
||||
| 'RATE_LIMIT'
|
||||
| 'PERMISSION'
|
||||
| 'CHANNEL_UNAVAILABLE'
|
||||
| 'NETWORK'
|
||||
| 'CONFIG'
|
||||
| 'GATEWAY'
|
||||
| 'UNKNOWN';
|
||||
|
||||
export class AppError extends Error {
|
||||
code: AppErrorCode;
|
||||
cause?: unknown;
|
||||
details?: Record<string, unknown>;
|
||||
|
||||
constructor(code: AppErrorCode, message: string, cause?: unknown, details?: Record<string, unknown>) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.cause = cause;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
export function mapBackendErrorCode(code?: string): AppErrorCode {
|
||||
switch (code) {
|
||||
case 'TIMEOUT':
|
||||
return 'TIMEOUT';
|
||||
case 'PERMISSION':
|
||||
return 'PERMISSION';
|
||||
case 'GATEWAY':
|
||||
return 'GATEWAY';
|
||||
case 'VALIDATION':
|
||||
return 'CONFIG';
|
||||
case 'UNSUPPORTED':
|
||||
return 'CHANNEL_UNAVAILABLE';
|
||||
default:
|
||||
return 'UNKNOWN';
|
||||
}
|
||||
}
|
||||
|
||||
function classifyMessage(message: string): AppErrorCode {
|
||||
const lower = message.toLowerCase();
|
||||
|
||||
if (
|
||||
lower.includes('invalid ipc channel')
|
||||
|| lower.includes('no handler registered')
|
||||
|| lower.includes('window is not defined')
|
||||
|| lower.includes('unsupported')
|
||||
) {
|
||||
return 'CHANNEL_UNAVAILABLE';
|
||||
}
|
||||
if (
|
||||
lower.includes('invalid authentication')
|
||||
|| lower.includes('unauthorized')
|
||||
|| lower.includes('auth failed')
|
||||
|| lower.includes('401')
|
||||
) {
|
||||
return 'AUTH_INVALID';
|
||||
}
|
||||
if (lower.includes('timeout') || lower.includes('timed out') || lower.includes('abort')) {
|
||||
return 'TIMEOUT';
|
||||
}
|
||||
if (lower.includes('rate limit') || lower.includes('429')) {
|
||||
return 'RATE_LIMIT';
|
||||
}
|
||||
if (
|
||||
lower.includes('permission')
|
||||
|| lower.includes('forbidden')
|
||||
|| lower.includes('denied')
|
||||
|| lower.includes('403')
|
||||
) {
|
||||
return 'PERMISSION';
|
||||
}
|
||||
if (
|
||||
lower.includes('network')
|
||||
|| lower.includes('fetch')
|
||||
|| lower.includes('econnrefused')
|
||||
|| lower.includes('econnreset')
|
||||
|| lower.includes('enotfound')
|
||||
) {
|
||||
return 'NETWORK';
|
||||
}
|
||||
if (lower.includes('gateway')) {
|
||||
return 'GATEWAY';
|
||||
}
|
||||
if (lower.includes('config') || lower.includes('invalid') || lower.includes('validation') || lower.includes('400')) {
|
||||
return 'CONFIG';
|
||||
}
|
||||
|
||||
return 'UNKNOWN';
|
||||
}
|
||||
|
||||
export function normalizeAppError(err: unknown, details?: Record<string, unknown>): AppError {
|
||||
if (err instanceof AppError) {
|
||||
return new AppError(err.code, err.message, err.cause ?? err, { ...(err.details ?? {}), ...(details ?? {}) });
|
||||
}
|
||||
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
return new AppError(classifyMessage(message), message, err, details);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user