Files
dify/cli/src/errors/base.ts
2026-06-01 01:32:16 +00:00

82 lines
2.1 KiB
TypeScript

import type { ErrorCodeValue, ExitCodeValue } from './codes'
import { ErrorCode, exitFor } from './codes'
export type BaseErrorOptions = {
readonly code: ErrorCodeValue
readonly message: string
readonly hint?: string
readonly httpStatus?: number
readonly method?: string
readonly url?: string
readonly cause?: unknown
}
export class BaseError extends Error {
readonly code: ErrorCodeValue
readonly hint?: string
readonly httpStatus?: number
readonly method?: string
readonly url?: string
constructor(opts: BaseErrorOptions) {
super(opts.message, opts.cause === undefined ? undefined : { cause: opts.cause })
this.name = 'BaseError'
this.code = opts.code
this.hint = opts.hint
this.httpStatus = opts.httpStatus
this.method = opts.method
this.url = opts.url
Object.setPrototypeOf(this, new.target.prototype)
}
exit(): ExitCodeValue {
return exitFor(this.code)
}
override toString(): string {
return this.hint
? `${this.code}: ${this.message} (hint: ${this.hint})`
: `${this.code}: ${this.message}`
}
withHint(hint: string): BaseError {
return new BaseError({ ...this.snapshot(), hint })
}
withHttpStatus(httpStatus: number): BaseError {
return new BaseError({ ...this.snapshot(), httpStatus })
}
withRequest(method: string, url: string): BaseError {
return new BaseError({ ...this.snapshot(), method, url })
}
wrap(cause: unknown): BaseError {
return new BaseError({ ...this.snapshot(), cause })
}
private snapshot(): BaseErrorOptions {
return {
code: this.code,
message: this.message,
hint: this.hint,
httpStatus: this.httpStatus,
method: this.method,
url: this.url,
cause: this.cause,
}
}
}
export function newError(code: ErrorCodeValue, message: string): BaseError {
return new BaseError({ code, message })
}
export function isBaseError(value: unknown): value is BaseError {
return value instanceof BaseError
}
export function unknownError(message: string, cause?: unknown): BaseError {
return new BaseError({ code: ErrorCode.Unknown, message, cause })
}