Skip to content

feat: implement typed error taxonomy and custom error classes (#18)#38

Merged
truthixify merged 2 commits into
wraith-protocol:developfrom
TheDEV111:feat/typed-errors
Jun 4, 2026
Merged

feat: implement typed error taxonomy and custom error classes (#18)#38
truthixify merged 2 commits into
wraith-protocol:developfrom
TheDEV111:feat/typed-errors

Conversation

@TheDEV111

@TheDEV111 TheDEV111 commented May 31, 2026

Copy link
Copy Markdown

closes #18

📝 Overview & Summary

Currently, the SDK throws plain, generic Error instances throughout its modules. This forces consumers to use brittle string-matching patterns in try/catch blocks to programmatically distinguish between specific error conditions (e.g. invalid meta-addresses, RPC failures, or view-tag mismatches).

This PR resolves Issue #18 by implementing a granular, typed hierarchy of custom error classes under src/errors.ts (re-exported from the SDK root entry point). These custom classes extend the native JavaScript Error class (guaranteeing runtime backwards-compatibility) while carrying enumerable, structured metadata payloads, stable error codes, and dynamic documentation links.


🛠️ Detailed Scope of Changes

1. The Error Hierarchy (src/errors.ts)

We have established a robust abstract taxonomy dividing errors into five primary functional domains:

WraithError (Abstract Base)
├── WraithInputError
│   ├── InvalidMetaAddressError
│   ├── InvalidNameError
│   ├── InvalidSignatureError
│   └── InvalidScalarError
├── WraithCryptoError
│   ├── KeyDerivationFailedError
│   ├── ViewTagMismatchError
│   └── ECDHFailedError
├── WraithNetworkError
│   ├── RPCRequestError
│   ├── RPCRetryExhaustedError
│   └── RetentionExceededError
├── WraithContractError
│   ├── NameNotFoundError
│   ├── NameAlreadyRegisteredError
│   ├── InsufficientAuthError
│   └── ContractRevertError
└── WraithBuilderError
    ├── InsufficientBalanceError
    └── UnsupportedAssetError

2. Properties & Serialization Support

Every subclass instances includes:

  • name: Automatically matches the class name.
  • code: A stable serializable constant string (e.g. "WRAITH/INPUT/INVALID_SIGNATURE") to retain class identity across network boundaries.
  • context: A structured object containing domain-specific parameters (e.g. statusCode, expectedLength, actualLength).
  • docsLink: A direct link referencing the specific error details in the documentation guide.
  • JSON Serialization: Native support via toJSON() on WraithError to ensure custom properties serialize cleanly with JSON.stringify(error).

3. Codebase-wide Refactoring

  • Generic Throw Replacements: Swept all modules across all supported chains (CKB, EVM, Solana, and Stellar) and the core Wraith Agent Client to replace plain throw new Error(...) calls with their typed equivalents.
  • JSDoc Enhancements: Updated @throws comments across public functions to document specific error behavior.

4. Testing & QA

  • Unit Tests (test/errors.test.ts): Added 17 unit tests verifying instanceof correctness (including ancestor matching like WraithInputError), name/code/docsLink generation, property preservation, and serialization.
  • Suite Adjustment: Updated existing signature-rejection test suites on all chains to expect the typed InvalidSignatureError exceptions.

5. Documentation

  • User Guide (docs/errors.md): Wrote a complete, premium-quality developer guide containing the class tree, property mappings, stable codes reference table, and rich try/catch integration examples.
  • Changelog (CHANGELOG.md): Noted the change in a new changelog file, warning developers about message string formatting adjustments.

⚠️ Impact & Migration Path

  • Runtime Non-Breaking: Applications that catch exceptions as generic Error instances remain unaffected because all custom classes inherit from Error.
  • Typing-Breaking for Brittle Matchers: Code relying on substring checks against error.message (e.g. .toThrow('Expected 65-byte signature')) will break. Integrators must update their catch statements to use modern instanceof checking:
import { InvalidSignatureError } from '@wraith-protocol/sdk';

try {
  const keys = deriveStealthKeys(badSig);
} catch (e) {
  if (e instanceof InvalidSignatureError) {
    console.error(`Expected signature length: ${e.context.expectedLength}`);
  }
}

✅ Verification & Testing Done

  • Vitest Results: Ran pnpm test, verifying that all 151 unit and E2E tests successfully pass.
  • Precommit Check: Format checking and TypeScript generation executed successfully under Husky hooks:
    ESM dist/index.js                 5.10 KB
    CJS dist/index.cjs                7.89 KB
    DTS dist/index.d.ts               8.62 KB
    ⚡️ Build success in 582ms

@drips-wave

drips-wave Bot commented May 31, 2026

Copy link
Copy Markdown

@TheDEV111 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@truthixify truthixify changed the base branch from main to develop June 1, 2026 15:33
@truthixify

Copy link
Copy Markdown
Contributor

The error hierarchy (src/errors.ts, 230 lines + 235 lines of tests) is the right shape. Same rebase situation.

git fetch origin
git rebase origin/develop
git push --force-with-lease

Keep src/errors.ts, test/errors.test.ts, the per-chain typed-throw migrations; resolve conflicts in files you didn't intend to rewrite by keeping develop's versions. Thanks @TheDEV111.

@truthixify

Copy link
Copy Markdown
Contributor

The error hierarchy + typed-throw migration sweep + tests are the right shape for issue #18.

Conflicts in 4 files, all overlap with #14's JSDoc additions:

  • src/index.ts
  • src/chains/stellar/deployments.ts
  • src/chains/stellar/keys.ts
  • src/chains/stellar/meta-address.ts
git fetch origin
git rebase origin/develop
git push --force-with-lease

For each conflict: keep develop's JSDoc blocks intact and graft your typed-throw migrations on top (replacing throw new Error(...) with the matching WraithInputError / WraithCryptoError subclass while keeping the JSDoc above).

Thanks @TheDEV111.

@TheDEV111

Copy link
Copy Markdown
Author

@truthixify fixed conflict, pls review

@truthixify

Copy link
Copy Markdown
Contributor

Clean rebase, test merge into develop is clean. Error hierarchy, typed-throw sweep across per-chain modules, and tests all land. Merging. Thanks @TheDEV111.

@truthixify truthixify merged commit 329e1c7 into wraith-protocol:develop Jun 4, 2026
1 check failed
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.

Typed error taxonomy + custom error classes

2 participants