feat: enforce tagged error messages
This commit is contained in:
parent
cf80b5c470
commit
b30440ec26
31 changed files with 466 additions and 47 deletions
|
|
@ -5,6 +5,7 @@ import { Cause, Context, Effect, Layer, Schema, Scope } from "effect"
|
|||
import { ModelV2 } from "./model"
|
||||
import { ProviderV2 } from "./provider"
|
||||
import { State } from "./state"
|
||||
import { errorMessage } from "./util/error"
|
||||
|
||||
type SDK = any
|
||||
|
||||
|
|
@ -123,7 +124,11 @@ function prepareOptions(model: ModelV2.Info, pkg: string) {
|
|||
export class InitError extends Schema.TaggedErrorClass<InitError>()("AISDK.InitError", {
|
||||
providerID: ProviderV2.ID,
|
||||
cause: Schema.Defect(),
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Failed to initialize AI SDK provider ${this.providerID}: ${errorMessage(this.cause)}`
|
||||
}
|
||||
}
|
||||
|
||||
function initError(providerID: ProviderV2.ID) {
|
||||
return Effect.catchCause((cause) => Effect.fail(new InitError({ providerID, cause: Cause.squash(cause) })))
|
||||
|
|
|
|||
|
|
@ -30,7 +30,11 @@ export class DestinationProjectMismatchError extends Schema.TaggedErrorClass<Des
|
|||
expected: ProjectV2.ID,
|
||||
actual: ProjectV2.ID,
|
||||
},
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `Destination project ${this.actual} does not match session project ${this.expected}`
|
||||
}
|
||||
}
|
||||
|
||||
export class ApplyChangesError extends Schema.TaggedErrorClass<ApplyChangesError>()("MoveSession.ApplyChangesError", {
|
||||
message: Schema.String,
|
||||
|
|
|
|||
|
|
@ -30,11 +30,19 @@ export interface RemoveInput {
|
|||
|
||||
export class StaleContentError extends Schema.TaggedErrorClass<StaleContentError>()("FileMutation.StaleContentError", {
|
||||
path: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `File changed since it was read: ${this.path}`
|
||||
}
|
||||
}
|
||||
|
||||
export class TargetExistsError extends Schema.TaggedErrorClass<TargetExistsError>()("FileMutation.TargetExistsError", {
|
||||
path: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `File already exists: ${this.path}`
|
||||
}
|
||||
}
|
||||
|
||||
export interface WriteResult {
|
||||
readonly operation: "write"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,11 @@ import { FileSystem } from "./filesystem"
|
|||
export class ResizerUnavailableError extends Schema.TaggedErrorClass<ResizerUnavailableError>()(
|
||||
"Image.ResizerUnavailableError",
|
||||
{},
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return "Image resizer is unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
export class DecodeError extends Schema.TaggedErrorClass<DecodeError>()("Image.DecodeError", {
|
||||
resource: Schema.String,
|
||||
|
|
|
|||
|
|
@ -169,11 +169,20 @@ export type AttemptStatus = typeof AttemptStatus.Type
|
|||
|
||||
export class CodeRequiredError extends Schema.TaggedErrorClass<CodeRequiredError>()("Integration.CodeRequired", {
|
||||
attemptID: AttemptID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Authorization code required for OAuth attempt ${this.attemptID}`
|
||||
}
|
||||
}
|
||||
|
||||
export class AuthorizationError extends Schema.TaggedErrorClass<AuthorizationError>()("Integration.Authorization", {
|
||||
cause: Schema.Defect(),
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
const detail = this.cause instanceof Error ? this.cause.message : String(this.cause)
|
||||
return `Integration authorization failed${detail ? `: ${detail}` : ""}`
|
||||
}
|
||||
}
|
||||
|
||||
export type Error = CodeRequiredError | AuthorizationError
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,13 @@ export type ResolveInput = typeof ResolveInput.Type
|
|||
export class PathError extends Schema.TaggedErrorClass<PathError>()("LocationMutation.PathError", {
|
||||
path: Schema.String,
|
||||
reason: Schema.Literals(["relative_escape", "location_escape", "non_directory_ancestor"]),
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
if (this.reason === "relative_escape") return `Relative path escapes the location: ${this.path}`
|
||||
if (this.reason === "location_escape") return `Path resolves outside the location: ${this.path}`
|
||||
return `Path has a non-directory ancestor: ${this.path}`
|
||||
}
|
||||
}
|
||||
|
||||
export interface ExternalDirectoryAuthorization {
|
||||
readonly action: "external_directory"
|
||||
|
|
|
|||
|
|
@ -11,12 +11,18 @@ import { LayerNode } from "./effect/layer-node"
|
|||
import { filesystem } from "./effect/layer-node-platform"
|
||||
import { makeRuntime } from "./effect/runtime"
|
||||
import { NpmConfig } from "./npm-config"
|
||||
import { errorMessage } from "./util/error"
|
||||
|
||||
export class InstallFailedError extends Schema.TaggedErrorClass<InstallFailedError>()("NpmInstallFailedError", {
|
||||
add: Schema.Array(Schema.String).pipe(Schema.optional),
|
||||
dir: Schema.String,
|
||||
cause: Schema.optional(Schema.Defect()),
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
const detail = this.cause === undefined ? undefined : errorMessage(this.cause)
|
||||
return `Failed to install ${this.add?.join(", ") || "dependencies"} in ${this.dir}${detail ? `: ${detail}` : ""}`
|
||||
}
|
||||
}
|
||||
|
||||
export interface EntryPoint {
|
||||
readonly directory: string
|
||||
|
|
|
|||
|
|
@ -83,19 +83,36 @@ export const Event = {
|
|||
}),
|
||||
}
|
||||
|
||||
export class RejectedError extends Schema.TaggedErrorClass<RejectedError>()("PermissionV2.RejectedError", {}) {}
|
||||
export class RejectedError extends Schema.TaggedErrorClass<RejectedError>()("PermissionV2.RejectedError", {}) {
|
||||
override get message() {
|
||||
return "The user rejected this permission request"
|
||||
}
|
||||
}
|
||||
|
||||
export class CorrectedError extends Schema.TaggedErrorClass<CorrectedError>()("PermissionV2.CorrectedError", {
|
||||
feedback: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `The user rejected this permission request with feedback: ${this.feedback}`
|
||||
}
|
||||
}
|
||||
|
||||
export class DeniedError extends Schema.TaggedErrorClass<DeniedError>()("PermissionV2.DeniedError", {
|
||||
rules: PermissionSchema.Ruleset,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
if (this.rules.length === 0) return "Permission denied by configured rules"
|
||||
return `Permission denied by configured rules: ${this.rules.map((rule) => `${rule.action} ${rule.resource}`).join(", ")}`
|
||||
}
|
||||
}
|
||||
|
||||
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("PermissionV2.NotFoundError", {
|
||||
requestID: ID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Permission request not found: ${this.requestID}`
|
||||
}
|
||||
}
|
||||
|
||||
export type Error = DeniedError | RejectedError | CorrectedError
|
||||
|
||||
|
|
|
|||
|
|
@ -58,32 +58,56 @@ export type ListEntry = typeof ListEntry.Type
|
|||
export class SourceDirectoryNotFoundError extends Schema.TaggedErrorClass<SourceDirectoryNotFoundError>()(
|
||||
"ProjectCopy.SourceDirectoryNotFoundError",
|
||||
{ directory: AbsolutePath },
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `Project copy source directory not found: ${this.directory}`
|
||||
}
|
||||
}
|
||||
|
||||
export class DestinationExistsError extends Schema.TaggedErrorClass<DestinationExistsError>()(
|
||||
"ProjectCopy.DestinationExistsError",
|
||||
{ directory: AbsolutePath },
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `Project copy destination already exists: ${this.directory}`
|
||||
}
|
||||
}
|
||||
|
||||
export class DirectoryUnavailableError extends Schema.TaggedErrorClass<DirectoryUnavailableError>()(
|
||||
"ProjectCopy.DirectoryUnavailableError",
|
||||
{ directory: AbsolutePath },
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `Project copy directory is unavailable: ${this.directory}`
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidDirectoryError extends Schema.TaggedErrorClass<InvalidDirectoryError>()(
|
||||
"ProjectCopy.InvalidDirectoryError",
|
||||
{ directory: AbsolutePath },
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `Invalid project copy directory: ${this.directory}`
|
||||
}
|
||||
}
|
||||
|
||||
export class StrategyUnavailableError extends Schema.TaggedErrorClass<StrategyUnavailableError>()(
|
||||
"ProjectCopy.StrategyUnavailableError",
|
||||
{ strategy: StrategyID },
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `Project copy strategy is unavailable: ${this.strategy}`
|
||||
}
|
||||
}
|
||||
|
||||
export class DuplicateStrategyError extends Schema.TaggedErrorClass<DuplicateStrategyError>()(
|
||||
"ProjectCopy.DuplicateStrategyError",
|
||||
{ strategy: StrategyID },
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `Project copy strategy is already registered: ${this.strategy}`
|
||||
}
|
||||
}
|
||||
|
||||
export type Error =
|
||||
| SourceDirectoryNotFoundError
|
||||
|
|
|
|||
|
|
@ -94,11 +94,19 @@ export type Attachment = {
|
|||
|
||||
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Pty.NotFoundError", {
|
||||
ptyID: PtyID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `PTY session not found: ${this.ptyID}`
|
||||
}
|
||||
}
|
||||
|
||||
export class ExitedError extends Schema.TaggedErrorClass<ExitedError>()("Pty.ExitedError", {
|
||||
ptyID: PtyID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `PTY session has exited: ${this.ptyID}`
|
||||
}
|
||||
}
|
||||
|
||||
export const Event = {
|
||||
Created: EventV2.define({ type: "pty.created", schema: { info: Info } }),
|
||||
|
|
|
|||
|
|
@ -87,7 +87,11 @@ export class RejectedError extends Schema.TaggedErrorClass<RejectedError>()("Que
|
|||
|
||||
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("QuestionV2.NotFoundError", {
|
||||
requestID: ID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Question request not found: ${this.requestID}`
|
||||
}
|
||||
}
|
||||
|
||||
export interface AskInput {
|
||||
readonly sessionID: SessionSchema.ID
|
||||
|
|
|
|||
|
|
@ -83,21 +83,33 @@ type CompactInput = {
|
|||
|
||||
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Session.NotFoundError", {
|
||||
sessionID: SessionSchema.ID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Session not found: ${this.sessionID}`
|
||||
}
|
||||
}
|
||||
|
||||
export class OperationUnavailableError extends Schema.TaggedErrorClass<OperationUnavailableError>()(
|
||||
"Session.OperationUnavailableError",
|
||||
{
|
||||
operation: Schema.Literals(["move", "shell", "skill", "switchAgent", "compact", "wait"]),
|
||||
},
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `Session ${this.operation} is not available yet`
|
||||
}
|
||||
}
|
||||
|
||||
export { ContextSnapshotDecodeError, MessageDecodeError } from "./session/error"
|
||||
|
||||
export class PromptConflictError extends Schema.TaggedErrorClass<PromptConflictError>()("Session.PromptConflictError", {
|
||||
sessionID: SessionSchema.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Prompt message ${this.messageID} conflicts with an existing durable record in session ${this.sessionID}`
|
||||
}
|
||||
}
|
||||
|
||||
export type Error = NotFoundError | MessageDecodeError | OperationUnavailableError | PromptConflictError
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ export const find = Effect.fn("SessionInput.find")(function* (db: DatabaseServic
|
|||
return row === undefined ? undefined : fromRow(row)
|
||||
})
|
||||
|
||||
// oxlint-disable-next-line opencode/tagged-error-message -- internal defect sentinel for inconsistent projections
|
||||
export class LifecycleConflict extends Schema.TaggedErrorClass<LifecycleConflict>()("SessionInput.LifecycleConflict", {
|
||||
id: SessionMessage.ID,
|
||||
}) {}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,19 @@ export namespace EffectFlock {
|
|||
|
||||
export class LockTimeoutError extends Schema.TaggedErrorClass<LockTimeoutError>()("LockTimeoutError", {
|
||||
key: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Timed out acquiring lock: ${this.key}`
|
||||
}
|
||||
}
|
||||
|
||||
export class LockCompromisedError extends Schema.TaggedErrorClass<LockCompromisedError>()("LockCompromisedError", {
|
||||
detail: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Lock was compromised: ${this.detail}`
|
||||
}
|
||||
}
|
||||
|
||||
class ReleaseError extends Schema.TaggedErrorClass<ReleaseError>()("ReleaseError", {
|
||||
detail: Schema.String,
|
||||
|
|
@ -32,6 +40,7 @@ export namespace EffectFlock {
|
|||
}
|
||||
|
||||
/** Internal: signals "lock is held, retry later". Never leaks to callers. */
|
||||
// oxlint-disable-next-line opencode/tagged-error-message -- internal retry sentinel for lock contention
|
||||
class NotAcquired extends Schema.TaggedErrorClass<NotAcquired>()("NotAcquired", {}) {}
|
||||
|
||||
export type LockError = LockTimeoutError | LockCompromisedError
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@ export class DeniedError extends Schema.TaggedErrorClass<DeniedError>()("Permiss
|
|||
|
||||
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Permission.NotFoundError", {
|
||||
requestID: ID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Permission request not found: ${this.requestID}`
|
||||
}
|
||||
}
|
||||
|
||||
export type Error = DeniedError | RejectedError | CorrectedError
|
||||
|
|
|
|||
|
|
@ -3,50 +3,86 @@ import { Schema } from "effect"
|
|||
|
||||
export class SessionNotFoundError extends Schema.TaggedErrorClass<SessionNotFoundError>()("ACPSessionNotFoundError", {
|
||||
sessionId: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `session not found: ${this.sessionId}`
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidConfigOptionError extends Schema.TaggedErrorClass<InvalidConfigOptionError>()(
|
||||
"ACPInvalidConfigOptionError",
|
||||
{
|
||||
configId: Schema.String,
|
||||
},
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `unknown config option: ${this.configId}`
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidModelError extends Schema.TaggedErrorClass<InvalidModelError>()("ACPInvalidModelError", {
|
||||
modelId: Schema.String,
|
||||
providerId: Schema.optional(Schema.String),
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `model not found: ${this.modelId}`
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidEffortError extends Schema.TaggedErrorClass<InvalidEffortError>()("ACPInvalidEffortError", {
|
||||
effort: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `effort not found: ${this.effort}`
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidModeError extends Schema.TaggedErrorClass<InvalidModeError>()("ACPInvalidModeError", {
|
||||
mode: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `mode not found: ${this.mode}`
|
||||
}
|
||||
}
|
||||
|
||||
export class AuthRequiredError extends Schema.TaggedErrorClass<AuthRequiredError>()("ACPAuthRequiredError", {
|
||||
providerId: Schema.optional(Schema.String),
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return "provider authentication required"
|
||||
}
|
||||
}
|
||||
|
||||
export class UnknownAuthMethodError extends Schema.TaggedErrorClass<UnknownAuthMethodError>()(
|
||||
"ACPUnknownAuthMethodError",
|
||||
{
|
||||
methodId: Schema.String,
|
||||
},
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `unknown auth method: ${this.methodId}`
|
||||
}
|
||||
}
|
||||
|
||||
export class UnsupportedOperationError extends Schema.TaggedErrorClass<UnsupportedOperationError>()(
|
||||
"ACPUnsupportedOperationError",
|
||||
{
|
||||
method: Schema.String,
|
||||
},
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return `method not found: ${this.method}`
|
||||
}
|
||||
}
|
||||
|
||||
export class ServiceFailureError extends Schema.TaggedErrorClass<ServiceFailureError>()("ACPServiceFailureError", {
|
||||
safeMessage: Schema.String,
|
||||
service: Schema.optional(Schema.String),
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return this.safeMessage
|
||||
}
|
||||
}
|
||||
|
||||
export type Error =
|
||||
| SessionNotFoundError
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const wordmark = [
|
|||
`▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀ ▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀`,
|
||||
]
|
||||
|
||||
// oxlint-disable-next-line opencode/tagged-error-message -- CLI cancellation intentionally renders without an error message.
|
||||
export class CancelledError extends Schema.TaggedErrorClass<CancelledError>()("UICancelledError", {}) {}
|
||||
|
||||
export const Style = {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ export interface Runner<A, E = never> {
|
|||
readonly cancel: Effect.Effect<void>
|
||||
}
|
||||
|
||||
// oxlint-disable-next-line opencode/tagged-error-message -- Internal coordinator signal, not a user-facing error.
|
||||
export class Cancelled extends Schema.TaggedErrorClass<Cancelled>()("RunnerCancelled", {}) {}
|
||||
// oxlint-disable-next-line opencode/tagged-error-message -- Internal coordinator signal, not a user-facing error.
|
||||
export class Busy extends Schema.TaggedErrorClass<Busy>()("RunnerBusy", {}) {}
|
||||
|
||||
interface RunHandle<A, E> {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,11 @@ export type Diagnostic = VSCodeDiagnostic
|
|||
export class InitializeError extends Schema.TaggedErrorClass<InitializeError>()("LSPInitializeError", {
|
||||
serverID: Schema.String,
|
||||
cause: Schema.optional(Schema.Defect()),
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Failed to initialize LSP server: ${this.serverID}`
|
||||
}
|
||||
}
|
||||
|
||||
type DocumentDiagnosticReport = {
|
||||
items?: Diagnostic[]
|
||||
|
|
|
|||
|
|
@ -80,7 +80,11 @@ export const Failed = NamedError.create("MCPFailed", {
|
|||
|
||||
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("MCP.NotFoundError", {
|
||||
name: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `MCP server not found: ${this.name}`
|
||||
}
|
||||
}
|
||||
|
||||
type MCPClient = Client
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,11 @@ export type UpdatePayload = Types.DeepMutable<Schema.Schema.Type<typeof UpdatePa
|
|||
|
||||
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Project.NotFoundError", {
|
||||
projectID: ProjectV2.ID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Project not found: ${this.projectID}`
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Effect service
|
||||
|
|
|
|||
|
|
@ -67,16 +67,28 @@ export type CallbackInput = Schema.Schema.Type<typeof CallbackInput>
|
|||
|
||||
export class OauthMissing extends Schema.TaggedErrorClass<OauthMissing>()("ProviderAuthOauthMissing", {
|
||||
providerID: ProviderV2.ID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `No pending OAuth authorization for provider: ${this.providerID}`
|
||||
}
|
||||
}
|
||||
|
||||
export class OauthCodeMissing extends Schema.TaggedErrorClass<OauthCodeMissing>()("ProviderAuthOauthCodeMissing", {
|
||||
providerID: ProviderV2.ID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `OAuth authorization code is required for provider: ${this.providerID}`
|
||||
}
|
||||
}
|
||||
|
||||
export class OauthCallbackFailed extends Schema.TaggedErrorClass<OauthCallbackFailed>()(
|
||||
"ProviderAuthOauthCallbackFailed",
|
||||
{},
|
||||
) {}
|
||||
) {
|
||||
override get message() {
|
||||
return "OAuth callback failed"
|
||||
}
|
||||
}
|
||||
|
||||
export class ValidationFailed extends Schema.TaggedErrorClass<ValidationFailed>()("ProviderAuthValidationFailed", {
|
||||
field: Schema.String,
|
||||
|
|
|
|||
|
|
@ -98,7 +98,11 @@ export class RejectedError extends Schema.TaggedErrorClass<RejectedError>()("Que
|
|||
|
||||
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Question.NotFoundError", {
|
||||
requestID: QuestionID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Question request not found: ${this.requestID}`
|
||||
}
|
||||
}
|
||||
|
||||
interface PendingEntry {
|
||||
info: Request
|
||||
|
|
|
|||
|
|
@ -454,7 +454,11 @@ export const getUsage = (input: { model: Provider.Model; usage: Usage; metadata?
|
|||
|
||||
export class BusyError extends Schema.TaggedErrorClass<BusyError>()("SessionBusyError", {
|
||||
sessionID: SessionID,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Session is busy: ${this.sessionID}`
|
||||
}
|
||||
}
|
||||
|
||||
export type NotFound = NotFoundError
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,11 @@ export class NameMismatchError extends Schema.TaggedErrorClass<NameMismatchError
|
|||
path: Schema.String,
|
||||
expected: Schema.String,
|
||||
actual: Schema.String,
|
||||
}) {}
|
||||
}) {
|
||||
override get message() {
|
||||
return `Skill name mismatch at ${this.path}: expected "${this.expected}", got "${this.actual}"`
|
||||
}
|
||||
}
|
||||
|
||||
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Skill.NotFoundError", {
|
||||
name: Schema.String,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ const MAX_BYTES_LABEL = `${MAX_BYTES / 1024} KB`
|
|||
const SAMPLE_BYTES = 4096
|
||||
const SUPPORTED_IMAGE_MIMES = new Set(["image/jpeg", "image/png", "image/gif", "image/webp"])
|
||||
|
||||
// oxlint-disable-next-line opencode/tagged-error-message -- Internal sentinel used only to terminate the read stream.
|
||||
class ReadStop extends Schema.TaggedErrorClass<ReadStop>()("ReadStop", {}) {}
|
||||
|
||||
// `offset` and `limit` were originally `z.coerce.number()` — the runtime
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue