vf-error-handling
Use when creating new errors, migrating error classes to registry, catching/handling errors, or working with the VeryfrontError system
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when creating new errors, migrating error classes to registry, catching/handling errors, or working with the VeryfrontError system
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Build, test, push, deploy, and verify with rollback through Git on failure.
Build and run AI apps and agents with Veryfront CLI
Development flywheel - autonomous cycle of run, observe, fix, verify. Use for continuous development with browser automation.
Build Veryfront apps. Use for real-time errors, route preview, HMR control, and scaffolding pages/APIs/components/AI tools.
Onboard to veryfront-code architecture, testing, conventions, and PR process.
Diagnose and fix build failures using structured error output.
| name | vf-error-handling |
| description | Use when creating new errors, migrating error classes to registry, catching/handling errors, or working with the VeryfrontError system |
Veryfront uses a centralized error registry with slug-based identification. All errors extend VeryfrontError and are created via defineError().
Core principle: Never throw raw Error. Use the registry. Never identify errors by class name. Use slugs.
// In src/errors/error-registry.ts
import { defineError } from "./types.ts";
export const MY_NEW_ERROR = defineError({
slug: "my-new-error", // kebab-case, unique
category: "RUNTIME", // CONFIG | BUILD | RUNTIME | ROUTE | MODULE | SERVER | BOUNDARY | DEV | DEPLOY | AGENT | GENERAL
status: 500, // default HTTP status
title: "Something went wrong", // human-readable
suggestion: "Try doing X instead", // actionable fix
});
import { MY_NEW_ERROR } from "#veryfront/errors";
throw MY_NEW_ERROR.create({
detail: "Specific description of what happened",
context: { key: "value", relevantData: data },
cause: originalError, // optional: chain the original error
});
import { VeryfrontError } from "#veryfront/errors";
try {
riskyOperation();
} catch (error) {
if (error instanceof VeryfrontError && error.slug === "my-new-error") {
// Handle specific error
console.log(error.context.relevantData);
}
throw error; // Re-throw unknown errors
}
When replacing class FooError extends Error:
// src/errors/error-registry.ts
export const FOO_ERROR = defineError({
slug: "foo-error",
category: "RUNTIME",
status: 500,
title: "Foo operation failed",
suggestion: "Check the foo configuration",
});
// Before
throw new FooError("something failed", { details: data });
// After
throw FOO_ERROR.create({
detail: "something failed",
context: { details: data },
});
// Before
if (error instanceof FooError) { ... }
// After
if (error instanceof VeryfrontError && error.slug === "foo-error") { ... }
Follow the re-export chain and update each level:
src/module/types.ts — remove class, add registry import if neededsrc/module/index.ts — change exportindex.ts files up the chainsrc/module/index.test.ts — change typeof X === "function" to typeof X === "object"Delete the old error class file entirely. No backwards-compatibility shims.
| Field | Type | Purpose |
|---|---|---|
slug | string | Unique identifier (kebab-case) |
category | ErrorCategory | Error domain |
status | number | HTTP status code |
title | string | Human-readable title |
suggestion | string | Actionable fix |
detail | string | Specific instance description |
context | Record<string, unknown> | Structured metadata |
cause | Error | Original error (chain) |
instance | string | Request/instance identifier |
// Convert to Problem Details format for HTTP APIs
const problemDetails = error.toRFC9457();
// Returns: { type, title, status, detail, instance, ...extensions }
Five errors remain as local classes by design (not in registry):
SemaphoreTimeoutErrorTransformTreeTimeoutErrorNotSupportedErrorTimeoutErrorStreamTimeoutErrorDo not migrate these to the registry.
| Mistake | Fix |
|---|---|
throw new Error("msg") | Use registry: MY_ERROR.create({ detail: "msg" }) |
instanceof FooError | instanceof VeryfrontError && error.slug === "foo-error" |
Storing data in error.message | Use error.detail and error.context |
| Forgetting to update index.test.ts | Change function→object type check |
| Creating error class in module | Define in src/errors/error-registry.ts |