better-result Migrate v2
Upgrade better-result error definitions from the v1 TaggedError API to the v2 factory-based API.
When to Use
Use this skill when the user:
- is upgrading
better-resultfrom v1 to v2 - has classes that
extend TaggedErrordirectly - still uses
TaggedError.match,TaggedError.matchPartial, orTaggedError.isTaggedError - needs help rewriting constructor calls to the new object-based form
Reading Order
| Task | Files to Read |
| --- | --- |
| Plan and execute the migration | This file |
| See concrete before/after transforms | references/migration-patterns.md |
| Verify current library behavior | opensrc/ if present |
Quick API Diff
| v1 | v2 |
| --- | --- |
| class FooError extends TaggedError | class FooError extends TaggedError("FooError")<Props>() {} |
| readonly _tag = "FooError" as const | _tag generated by the factory |
| new FooError("123") | new FooError({ id: "123", message: "..." }) |
| TaggedError.match(...) | matchError(...) |
| TaggedError.matchPartial(...) | matchErrorPartial(...) |
| TaggedError.isTaggedError(...) | isTaggedError(...) or TaggedError.is(...) |
Migration Workflow
- Search for
extends TaggedErroracross the codebase. - For each class, extract:
- the
_tagliteral - constructor parameters and runtime properties
- any computed message or validation logic
- the
- Rewrite the class to
TaggedError("Tag")<Props>(). - If constructor logic exists, keep a custom constructor that accepts an object and calls
super({...}). - Update call sites from positional arguments to object arguments.
- Replace static helper usage with the new standalone helpers.
- Update imports.
- Run tests and search again for old API remnants.
Transformation Rules
- Simple class: remove
_tag, replace base class, move fields into the generic props object. - Computed message: keep a custom constructor and derive
messagebeforesuper(...). - Validation logic: preserve validation inside the custom constructor.
- Extra runtime fields: include them in the props object passed to
super(...). - Usages: migrate
new FooError(a, b)tonew FooError({ a, b, message })or an equivalent derived-message constructor.
Read references/migration-patterns.md before editing if the target classes are non-trivial.
Search Checklist
Search for all of these before and after the migration:
extends TaggedErrorreadonly _tag =TaggedError.matchTaggedError.matchPartialTaggedError.isTaggedErrornewcall sites for migrated error classes
Completion Criteria
A migration is complete when:
- no classes directly extend the old v1
TaggedErrorbase class - migrated classes use
TaggedError("...")<...>() - call sites use the new constructor shape
- static helper calls are replaced with
matchError,matchErrorPartial, orisTaggedError - imports reflect the new helper functions
- tests pass with the upgraded package version
Common Pitfalls
- Dropping custom validation logic during the rewrite
- Forgetting to include
messagein the props shape - Updating class declarations but not constructor call sites
- Replacing
TaggedError.matchbut missingmatchPartialorisTaggedError - Migrating the type but not preserving extra runtime fields like timestamps or codes
In This Reference
| File | Purpose |
| --- | --- |
| references/migration-patterns.md | Detailed v1 → v2 before/after examples and import helper changes |
If opensrc/ exists, use it to confirm the exact v2 API exposed by the installed package.