Skip to content

chore: add error codes refactoring plan - #246

Merged
kojiwakayama merged 9 commits into
mainfrom
chore/error-codes-refactor-plan
Feb 6, 2026
Merged

kojiwakayama merged 9 commits into
mainfrom
chore/error-codes-refactor-plan

Conversation

@ariskemper

@ariskemper ariskemper commented Feb 6, 2026 •

Copy link
Copy Markdown
Contributor

Replace VF### numeric codes and schema enum with slug-based error identity, aligned with RFC 9457.

Full plan: plans/refactor_error_codes.md


Target State

  • error-codes.ts — deleted
  • error.schema.ts enum — deleted
  • Zero VF### or schema enum references in codebase
  • All HTTP responses use application/problem+json
  • Single error-registry.ts as the only source of error definitions

Tasks

Phase 1: Slug registry + RFC 9457 + tests

1.1–1.3 independent — run as parallel subagents

  • 1.1 Create src/errors/types.ts — ErrorDefinition type + ErrorCategory union
  • 1.2 Create src/errors/error-registry.ts — 69 error definitions
  • 1.3 Create src/errors/error-registry.test.ts — slug uniqueness + RFC 9457 shape tests

1.4 depends on 1.1–1.2

  • 1.4 Update src/errors/veryfront-error.ts — add slug, category, cause, toRFC9457()
  • 1.5 Update HTTP error serialization → application/problem+json

Phase 2: Migrate all references to slugs

2.1–2.5 independent — run as parallel subagents

  • 2.1 Migrate src/errors/catalog/*.ts → slug registry
  • 2.2 Migrate src/errors/agent-errors.ts → slug registry
  • 2.3 Migrate src/errors/build-errors.ts → slug registry
  • 2.4 Migrate src/errors/runtime-errors.ts → slug registry
  • 2.5 Migrate src/errors/system-errors.ts → slug registry

2.6–2.9 depend on 2.1–2.5

  • 2.6 Replace all error.code === "VF###" → error.slug === "..."
  • 2.7 Replace all error.code === "BUILD_ERROR" (schema enum) → slug checks
  • 2.8 Update error constructors to require slug
  • 2.9 Update all error tests to use slugs

Phase 3: Delete legacy code

3.1–3.3 independent — run as parallel subagents

  • 3.1 Delete src/errors/error-codes.ts
  • 3.2 Delete error enum from src/errors/schemas/error.schema.ts
  • 3.3 Update src/errors/index.ts — remove legacy exports

3.4–3.5 verify cleanup

  • 3.4 grep -r "VF[0-9]" src/ returns zero matches
  • 3.5 All tests pass

Phase 4: Documentation

4.1–4.2 independent — run as parallel subagents

  • 4.1 Set up https://veryfront.com/docs/errors/{slug} pages
  • 4.2 Redirect old /docs/errors/VF001 → /docs/errors/{slug} for all 60 codes
  • 4.3 Add integration tests for documentation URLs

Comment thread plans/refactor_error_codes.md Outdated
@ariskemper
ariskemper force-pushed the chore/error-codes-refactor-plan branch from 6b51a25 to dac0b4d Compare February 6, 2026 08:33

@kojiwakayama kojiwakayama left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Error Codes Refactoring Plan

Good foundation — the current state analysis is thorough and the category mapping is well thought out. A few areas need attention before this guides implementation.


Issues

1. Column header mismatch (line 143)

The Schema-Based Error Codes table uses Code as column header, but the values are UPPER_SNAKE_CASE names (like FILE_NOT_FOUND), not numeric codes. Every other table distinguishes Code (VF###) from Name (SNAKE_CASE).

-| Code                 | Description                          |
+| Name                 | Description                          |

2. Non-obvious prefix letter choices

Several category prefixes feel arbitrary and will be hard for devs to remember:

Category Prefix Issue
NETWORK VFW Why W?
CONFIG VFG G for confiG?
AGENT VFE E for agEnt?

Consider full-word prefixes (VFNET, VFCFG, VFAGT) or at minimum document the mnemonic reasoning.

3. Speculative AUTH category

The AUTH category (VFA001-VFA008) is entirely (new). A refactoring plan should focus on restructuring what exists. Speculative future codes should be clearly marked as "Reserved / Future" rather than listed alongside real migrations.

4. The "OTHER" (VFX) category is a code smell

CACHE_ERROR, FILE_WATCH_ERROR, and DEPLOYMENT_ERROR can be assigned to existing categories (INTERNAL, BUILD). An "other" bucket defeats the purpose of categorization.

5. Schema/VF### consolidation logic missing

Several errors are duplicated across systems (FILE_NOT_FOUND, RENDER_ERROR, SERVICE_OVERLOADED). The plan says "consolidate" but doesn't specify which system wins, whether schema codes are deprecated, or the merge strategy. This is the hardest part of the migration and deserves explicit treatment.

6. Breaking change strategy missing

Changing VF001 → VFN001 is a breaking change for anyone matching on error codes (log alerts, error handlers, docs URLs). The plan should address: backward compat / deprecation period, old→new code mapping, URL redirects for https://veryfront.com/docs/errors/{code}, and user communication.

7. Some categorization choices seem off

  • IMPORT_RESOLUTION_ERROR (VF401 → VFG004 CONFIG) — this is module resolution, not configuration
  • DYNAMIC_ROUTE_ERROR (VF303 → VFR004 RUNTIME) — route parsing is build-time
  • HMR_ERROR (VF502 → VFR007 RUNTIME) — dev-time tooling, not production runtime

8. No DEV category in new system

Current VF700-VF799 covers development errors. In the proposal these get scattered across RUNTIME and INTERNAL. Dev-only errors have different severity/handling than production errors — consider keeping a DEV category.


RFC 9457 (Problem Details for HTTP APIs) — consider adopting

While this plan focuses on internal taxonomy, the error response shape that consumers see should follow RFC 9457 (supersedes RFC 7807). Adopting it now — while restructuring — avoids doing this twice.

Introduce a slug as the canonical identifier

Each error should have a kebab-case slug derived from the name:

Code Name Slug
VFN001 CONFIG_NOT_FOUND config-not-found
VFR001 HYDRATION_MISMATCH hydration-mismatch
VFC004 PORT_IN_USE port-in-use

Three-layer error identity model

  1. Slug (primary, stable): config-not-found — used in the RFC 9457 type URI, never changes
  2. Code (internal): VFN001 — used for logging/debugging, may change with restructuring
  3. Category (grouping): NOT_FOUND — used for filtering/handling

The slug resolves the breaking change problem: if the type URI uses slugs (https://veryfront.com/docs/errors/config-not-found), you can restructure internal numbering (VF001 → VFN001) without breaking consumers.

RFC 9457 response shape

{
  "type": "https://veryfront.com/docs/errors/config-not-found",
  "title": "Configuration file not found",
  "status": 404,
  "detail": "Could not find veryfront.config.ts in /app/my-project",
  "code": "VFN001",
  "category": "NOT_FOUND",
  "suggestion": "Run 'vf init' to create a configuration file"
}

Where type, title, status, detail are standard RFC 9457 fields, and code, category, suggestion are Veryfront extension members (which the RFC explicitly supports).

Align categories with HTTP status codes

Category HTTP Status
NOT_FOUND 404
AUTH 401 / 403
PERMISSION 403
VALIDATION 400 / 422
CONFLICT 409
TIMEOUT 408 / 504
INTERNAL 500

The RFC says each problem type definition should specify its HTTP status code — this mapping should be documented in the plan.

The type URI doubles as documentation

The RFC says the type URI SHOULD resolve to HTML docs explaining how to fix the problem. Switching from /docs/errors/VFN001 to /docs/errors/config-not-found gives human-readable, stable URLs that survive code renumbering.


Minor

  • PR description duplicates the Implementation Checklist — could just reference the doc
  • Consider adding an "Error Code Lifecycle" section — what happens when a new error needs to be added?
  • HYDRATION_MISMATCH row has inconsistent spacing vs other rows in the VF### table

Verdict

Needs a second pass. Main gaps: prefix mnemonics, breaking change strategy, schema consolidation logic, and RFC 9457 alignment. The slug + three-layer identity model would make the whole system more robust and standards-compliant.

@ariskemper
ariskemper force-pushed the chore/error-codes-refactor-plan branch from dac0b4d to 89bcaed Compare February 6, 2026 08:45
kojiwakayama added a commit that referenced this pull request Feb 6, 2026
7 error classes extend plain Error instead of VeryfrontError and bypass
the centralized slug registry. This plan migrates them after the main
error codes refactoring (PR #246) is complete.

Also documents 5 intentionally local control-flow errors that should
remain as-is.
kwakayama pushed a commit that referenced this pull request Feb 6, 2026
Two follow-up plans to the error codes refactoring (#246):

- error_handling_middleware.md: Unified catch → serialize → respond
  pipeline at HTTP/CLI boundaries using RFC 9457
- error_observability.md: Structured logging with slugs, unified error
  metrics, tracing integration, Grafana dashboards and alerts
ariskemper and others added 7 commits February 6, 2026 12:53
Document all existing error codes and propose a new categorization system
with semantic prefixes (VALIDATION, AUTH, NOT_FOUND, PERMISSION, etc.)
to improve error handling consistency and developer experience.
Document all existing error codes and propose a new categorization system
with semantic prefixes (VALIDATION, AUTH, NOT_FOUND, PERMISSION, etc.)
to improve error handling consistency and developer experience.
- Replace numeric code system (VF###/VFN###) with slug-based identifiers
- Adopt RFC 9457 (Problem Details for HTTP APIs) for error response shape
- Define 11 domain-based categories (CONFIG, BUILD, RUNTIME, etc.)
- Add slug naming convention, programmatic usage examples, error chaining
- Add schema overlap resolution table with concrete migration mechanism
- Distinguish HTTP-facing vs CLI/build error requirements
- Include tests in Phase 1 instead of as a separate final phase
- Single unified error registry replacing duplicate documentation
- Add explicit target state: error-codes.ts and schema enum deleted
- Replace Phase 4 "deprecate" with Phase 3 "delete legacy code"
- Remove alias/compatibility language — all references migrated in-place
- Rename "Legacy" column to "Replaces" in registry tables
- Update file changes table: delete instead of deprecate
- Remove persuasion sections (why slugs, problems, benefits, principles)
- Restructure: execution plan first, reference data after
- Add subagent parallelism annotations to all phases
- Number all tasks with dependency callouts
- Merge duplicate sections, cut redundant RFC 9457 examples
- Replace numeric VF### codes with stable kebab-case slugs (e.g., "config-not-found")
- Add RFC 9457 (Problem Details for HTTP APIs) compliance with toRFC9457() method
- Create error-registry.ts as single source of truth with defineError() factory
- Delete legacy error-codes.ts and schemas/error.schema.ts
- Update all error classes, catalog files, and tests to use slug-based identity
- Update README.md with new slug-based error system documentation
@ariskemper
ariskemper force-pushed the chore/error-codes-refactor-plan branch from 85e66cb to a04c452 Compare February 6, 2026 11:54
ariskemper and others added 2 commits February 6, 2026 13:05
…structor

- Replace verbose `new VeryfrontError(msg, { slug: X.slug, ... })` with
  idiomatic `X.create({ detail, context })` across all consumer callsites
- Make VeryfrontErrorOptions extend ErrorCreateOptions to reduce duplication
- Add minimum slug length validation (3 chars) to registry tests
- Update README to show .create() as the primary usage pattern
@kojiwakayama
kojiwakayama merged commit 4060b3f into main Feb 6, 2026
12 checks passed
@kojiwakayama
kojiwakayama deleted the chore/error-codes-refactor-plan branch February 6, 2026 13:00
ariskemper pushed a commit that referenced this pull request Feb 6, 2026
7 error classes extend plain Error instead of VeryfrontError and bypass
the centralized slug registry. This plan migrates them after the main
error codes refactoring (PR #246) is complete.

Also documents 5 intentionally local control-flow errors that should
remain as-is.
kojiwakayama added a commit that referenced this pull request Feb 6, 2026
…slug registry (#247)

* chore: add plan for centralizing scattered error classes

7 error classes extend plain Error instead of VeryfrontError and bypass
the centralized slug registry. This plan migrates them after the main
error codes refactoring (PR #246) is complete.

Also documents 5 intentionally local control-flow errors that should
remain as-is.

* refactor: centralize 7 scattered error classes into VeryfrontError + slug registry

Replace 7 classes that extended plain Error with a centralized error
registry pattern using VeryfrontError + unique slugs for identification.

Migrated errors:
- VeryfrontAPIError → API_CLIENT_ERROR (api-client-error)
- ConfigValidationError → CONFIG_VALIDATION_FAILED (config-validation-failed)
- SecurityError → SECURITY_VIOLATION (security-violation)
- ValidationError → INPUT_VALIDATION_FAILED (input-validation-failed)
- TokenStorageError → TOKEN_STORAGE_ERROR (token-storage-error)
- CacheInvariantError → CACHE_INVARIANT_VIOLATION (cache-invariant-violation)
- FallbackExecutionError → FALLBACK_EXHAUSTED (fallback-exhausted)

* style: move import to top of file and add doc comments for clarity

- Move CACHE_INVARIANT_VIOLATION import to top of cache/paths.ts
- Add doc comment to CONFIG_VALIDATION_ERROR to distinguish it from
  CONFIG_VALIDATION_FAILED (schema-level 422 vs file-level 400)

---------

Co-authored-by: ariskemper <aris.github@gmail.com>
ariskemper added a commit that referenced this pull request Feb 9, 2026
…slug registry (#247)

* chore: add plan for centralizing scattered error classes

7 error classes extend plain Error instead of VeryfrontError and bypass
the centralized slug registry. This plan migrates them after the main
error codes refactoring (PR #246) is complete.

Also documents 5 intentionally local control-flow errors that should
remain as-is.

* refactor: centralize 7 scattered error classes into VeryfrontError + slug registry

Replace 7 classes that extended plain Error with a centralized error
registry pattern using VeryfrontError + unique slugs for identification.

Migrated errors:
- VeryfrontAPIError → API_CLIENT_ERROR (api-client-error)
- ConfigValidationError → CONFIG_VALIDATION_FAILED (config-validation-failed)
- SecurityError → SECURITY_VIOLATION (security-violation)
- ValidationError → INPUT_VALIDATION_FAILED (input-validation-failed)
- TokenStorageError → TOKEN_STORAGE_ERROR (token-storage-error)
- CacheInvariantError → CACHE_INVARIANT_VIOLATION (cache-invariant-violation)
- FallbackExecutionError → FALLBACK_EXHAUSTED (fallback-exhausted)

* style: move import to top of file and add doc comments for clarity

- Move CACHE_INVARIANT_VIOLATION import to top of cache/paths.ts
- Add doc comment to CONFIG_VALIDATION_ERROR to distinguish it from
  CONFIG_VALIDATION_FAILED (schema-level 422 vs file-level 400)

---------

Co-authored-by: ariskemper <aris.github@gmail.com>
ariskemper pushed a commit that referenced this pull request Feb 9, 2026
Two follow-up plans to the error codes refactoring (#246):

- error_handling_middleware.md: Unified catch → serialize → respond
  pipeline at HTTP/CLI boundaries using RFC 9457
- error_observability.md: Structured logging with slugs, unified error
  metrics, tracing integration, Grafana dashboards and alerts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants