Implement src/errors.ts with unit tests (ToolError + toToolError) #139

Closed
opened 2026-08-31 22:04:44 +00:00 by david · 1 comment
Owner

Summary

Implement extensions/mongodb/src/errors.ts — the ToolError class and the toToolError(err, context) categorizer that every tool uses to fail with clear, actionable errors — with unit tests.

Background

Depends on: #133

Runtime finding (from the sibling victorialogs extension): the pinned pi runtime hardcodes isError: false for any execute() that resolves normally — returning { isError: true } does NOT mark a tool call failed. Tools must throw a ToolError from execute()'s catch block to fail the call. This module centralizes that behavior.

All three tools (this milestone) wrap their driver call in try/catch and throw a categorized ToolError; messages must be actionable and must never include the full connection string (credentials stay out of tool output).

Documentation Required

A separate process downloads these into the listed folder before this issue is implemented. Check the folder for the actual reference material before starting.

docs/reference/mongodb-driver/ — for the driver's error classes used in categorization:

Implementation Details

  • ToolError — a class extending Error, carrying a category (string) and the formatted user-facing message.
  • toToolError(err: unknown, context: { host?: string; port?: string; db?: string }): never — always throws (return type never). Detect the category in this order:
    1. Connection failureerr instanceof MongoNetworkError || err instanceof MongoServerSelectionError (timeout, unreachable host) → Could not reach MongoDB at <host>:<port> — is it running and reachable? (<error message>).
    2. Auth failureerr instanceof MongoServerError && err.code === 18 (AuthenticationFailed) → MongoDB authentication failed — check MONGODB_URI credentials and authSource. (<error message>).
    3. Invalid filter/paramserr instanceof MongoInvalidArgumentError, bad EJSON input, or unknown collection → Invalid query: <error message>.
    4. Server error — other MongoServerError (e.g. code 26 NamespaceNotFound) → MongoDB server error: <error message>.
    5. Unexpected — anything else → Unexpected MongoDB error: <error message>.
  • Import error classes from "mongodb" (MongoNetworkError, MongoServerSelectionError, MongoServerError, MongoInvalidArgumentError). Use instanceof checks (per the driver's own guidance). Note MongoServerSelectionError may subclass MongoNetworkError — the category split above handles that; keep the check order as listed.
  • For the connection-failure message, use <host>:<port> from the context argument (parsed from the URI by the caller), never the raw URI.

Write co-located tests in src/errors.test.ts (bun test): one case per category, asserting the thrown message shape (contains the expected phrasing; does NOT contain a connection string / credentials).

Acceptance Criteria

  • ToolError carries a category and a formatted message.
  • Connection failure → message starts Could not reach MongoDB at ... and includes is it running and reachable?.
  • Auth failure (MongoServerError code 18) → message starts MongoDB authentication failed — check MONGODB_URI credentials and authSource..
  • Invalid params (MongoInvalidArgumentError / bad EJSON) → message starts Invalid query: .
  • Other server errors → message starts MongoDB server error: .
  • Anything else → Unexpected MongoDB error: .
  • No message in any case contains a full connection string or credentials.
  • bun test in extensions/mongodb/ is green for src/errors.ts.

Test Plan

cd extensions/mongodb
bun test   # errors tests green
## Summary Implement `extensions/mongodb/src/errors.ts` — the `ToolError` class and the `toToolError(err, context)` categorizer that every tool uses to fail with clear, actionable errors — with unit tests. ## Background **Depends on:** #133 **Runtime finding (from the sibling victorialogs extension):** the pinned pi runtime hardcodes `isError: false` for any `execute()` that resolves normally — returning `{ isError: true }` does NOT mark a tool call failed. Tools must **throw** a `ToolError` from `execute()`'s catch block to fail the call. This module centralizes that behavior. All three tools (this milestone) wrap their driver call in try/catch and throw a categorized `ToolError`; messages must be actionable and must **never include the full connection string** (credentials stay out of tool output). ## Documentation Required A separate process downloads these into the listed folder before this issue is implemented. Check the folder for the actual reference material before starting. **`docs/reference/mongodb-driver/`** — for the driver's error classes used in categorization: - https://github.com/mongodb/node-mongodb-native/blob/master/etc/notes/errors.md — the driver's error class tree; guidance to use `instanceof` checks on error classes rather than parsing `error.message`/`error.name` strings (messages may change between patch releases; class hierarchy is semver-guaranteed). - https://mongodb.github.io/node-mongodb-native/7.6/ — TypeDoc API reference index; error classes such as `MongoNetworkError`, `MongoServerSelectionError`, `MongoServerError`, `MongoInvalidArgumentError` are exported from `mongodb`. - https://www.mongodb.com/docs/drivers/node/current/ — driver guide index (context: connection and CRUD behavior behind the errors). ## Implementation Details - `ToolError` — a class extending `Error`, carrying a `category` (string) and the formatted user-facing message. - `toToolError(err: unknown, context: { host?: string; port?: string; db?: string }): never` — always throws (return type `never`). Detect the category in this order: 1. **Connection failure** — `err instanceof MongoNetworkError || err instanceof MongoServerSelectionError` (timeout, unreachable host) → `Could not reach MongoDB at <host>:<port> — is it running and reachable? (<error message>)`. 2. **Auth failure** — `err instanceof MongoServerError && err.code === 18` (AuthenticationFailed) → `MongoDB authentication failed — check MONGODB_URI credentials and authSource. (<error message>)`. 3. **Invalid filter/params** — `err instanceof MongoInvalidArgumentError`, bad EJSON input, or unknown collection → `Invalid query: <error message>`. 4. **Server error** — other `MongoServerError` (e.g. code 26 NamespaceNotFound) → `MongoDB server error: <error message>`. 5. **Unexpected** — anything else → `Unexpected MongoDB error: <error message>`. - Import error classes from `"mongodb"` (`MongoNetworkError`, `MongoServerSelectionError`, `MongoServerError`, `MongoInvalidArgumentError`). Use `instanceof` checks (per the driver's own guidance). Note `MongoServerSelectionError` may subclass `MongoNetworkError` — the category split above handles that; keep the check order as listed. - For the connection-failure message, use `<host>:<port>` from the `context` argument (parsed from the URI by the caller), never the raw URI. Write co-located tests in `src/errors.test.ts` (bun test): one case per category, asserting the thrown message shape (contains the expected phrasing; does NOT contain a connection string / credentials). ## Acceptance Criteria - [ ] `ToolError` carries a `category` and a formatted message. - [ ] Connection failure → message starts `Could not reach MongoDB at ...` and includes `is it running and reachable?`. - [ ] Auth failure (MongoServerError code 18) → message starts `MongoDB authentication failed — check MONGODB_URI credentials and authSource.`. - [ ] Invalid params (MongoInvalidArgumentError / bad EJSON) → message starts `Invalid query: `. - [ ] Other server errors → message starts `MongoDB server error: `. - [ ] Anything else → `Unexpected MongoDB error: `. - [ ] No message in any case contains a full connection string or credentials. - [ ] `bun test` in `extensions/mongodb/` is green for `src/errors.ts`. ## Test Plan ```bash cd extensions/mongodb bun test # errors tests green ```
david closed this issue 2026-09-01 00:13:34 +00:00
Author
Owner

pi-loop opened and merged a pull request for this issue: #156

pi-loop opened and merged a pull request for this issue: https://git.excelera.net/david/pi-extensions-and-skills/pulls/156
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
david/pi-extensions-and-skills#139
No description provided.