Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/benchmark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"dependencies": {
"@eventstore/db-client": "^6.2.1",
"@kurrent/bridge": "^0.1.3",
"@kurrent/bridge": "^0.1.5",
"tinybench": "^3.1.1"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/db-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"dependencies": {
"@grpc/grpc-js": "^1.14.3",
"@kurrent/bridge": "^0.1.3",
"@kurrent/bridge": "^0.1.5",
"@types/debug": "^4.1.12",
"@types/google-protobuf": "^3.15.12",
"@types/node": "^22.10.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/db-client/src/utils/CommandError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@ export const convertToCommandError = (error: Error): CommandError | Error => {
case StatusCode.DEADLINE_EXCEEDED:
return new DeadlineExceededError(error);
case StatusCode.UNAVAILABLE:
case StatusCode.INTERNAL:
case StatusCode.DATA_LOSS:
return new UnavailableError(error);
case StatusCode.UNAUTHENTICATED:
return new AccessDeniedError(error);
Expand Down
39 changes: 14 additions & 25 deletions packages/db-client/src/utils/convertBridgeError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,32 @@ import {
StreamNotFoundError,
StreamDeletedError,
AccessDeniedError,
UnavailableError,
DeadlineExceededError,
UnknownError,
} from "./CommandError";
import { ServiceError } from "@grpc/grpc-js";

// export const convertBridgeError = (
// error: ServiceError,
// streamName?: string
// ) => {
// const stream = streamName ?? "unknown stream";
//
// switch (error.name) {
// case StreamNotFoundError.name:
// throw new StreamNotFoundError(error, stream);
// case StreamDeletedError.name:
// throw StreamDeletedError.fromStreamName(stream);
// case NotLeaderError.name:
// throw new NotLeaderError(error);
// case AccessDeniedError.name:
// throw new AccessDeniedError(error);
// default:
// throw error;
// }
// };

export const convertBridgeError = (error: Error, streamName?: string) => {
const stream = streamName ?? "unknown stream";
const serviceError = error as ServiceError;

switch (error.name) {
case StreamNotFoundError.name:
case "StreamNotFoundError":
return new StreamNotFoundError(serviceError, stream);
case StreamDeletedError.name:
case "StreamDeletedError":
return StreamDeletedError.fromStreamName(stream);
case NotLeaderError.name:
case "NotLeaderError":
return new NotLeaderError(serviceError);
case AccessDeniedError.name:
case "AccessDeniedError":
return new AccessDeniedError(serviceError);
case "UnavailableError":
return new UnavailableError(serviceError);
case "DeadlineExceededError":
return new DeadlineExceededError(serviceError);
case "UnknownError":
return new UnknownError(serviceError);
default:
return error;
return new UnknownError(serviceError);
}
Comment on lines 16 to 33
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Unknown errors get masked 🐞 Bug ≡ Correctness

convertBridgeError now converts any unrecognized thrown value into UnknownError, so non-bridge
exceptions (e.g., bugs thrown while converting/yielding events) get misclassified and lose their
original error type/stack. This is especially problematic because readStream/readAll catch broadly
and route all exceptions through convertBridgeError.
Agent Prompt
## Issue description
`convertBridgeError` now wraps *all* unrecognized errors into `UnknownError`. Because `readStream` / `readAll` catch broadly around async iteration, this change masks non-bridge exceptions (e.g., `TypeError`, conversion bugs) and discards the original error identity/stack.

## Issue Context
The bridge conversion helper should only translate *known* bridge-originated errors. Unexpected errors should propagate unchanged (or be wrapped while preserving the original error as `cause` and keeping the original stack).

## Fix Focus Areas
- packages/db-client/src/utils/convertBridgeError.ts[12-33]
- packages/db-client/src/streams/readStream.ts[114-126]
- packages/db-client/src/streams/readAll.ts[84-96]

## Suggested approach
- In `convertBridgeError`, before switching/wrapping, detect whether the error is a bridge/grpc-like error (e.g., has `code` and/or `metadata`) or matches a known bridge error name.
- If it’s not a recognized bridge error, return/throw the original `error` unchanged.
- If you still want to map unknown *bridge* errors, wrap them but preserve the original error via `cause` (and/or attach the original error object on the wrapper) so debugging remains possible.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

};
Loading
Loading