fix: Preserve original gRPC error cause in rewindInstance and restartOrchestration#200
fix: Preserve original gRPC error cause in rewindInstance and restartOrchestration#200YunchuWang wants to merge 1 commit intomainfrom
Conversation
…tion
The rewindInstance and restartOrchestration methods in TaskHubGrpcClient
catch gRPC errors and rethrow new Error objects with user-friendly
messages, but discard the original error. This loses valuable debugging
information (gRPC metadata, status details, and stack traces).
Changes:
- Add { cause: e } to all rethrown errors in rewindInstance, preserving
the original gRPC ServiceError for debugging
- Add { cause: e } to all rethrown errors in restartOrchestration
- Standardize gRPC error detection in rewindInstance to use
'instanceof Error' (consistent with restartOrchestration) instead of
duck-typing with 'typeof e === "object"'
- Add comprehensive unit tests verifying error cause preservation for
all handled gRPC status codes (NOT_FOUND, FAILED_PRECONDITION,
UNIMPLEMENTED, CANCELLED) and passthrough of unrecognized errors
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes loss of diagnostic information in the DurableTask JS SDK client by preserving the original gRPC ServiceError as the cause when TaskHubGrpcClient.rewindInstance() and TaskHubGrpcClient.restartOrchestration() wrap errors, aligning with existing error-wrapping patterns in the repo.
Changes:
- Preserve original caught gRPC errors via
new Error(message, { cause: e })inrewindInstanceandrestartOrchestration. - Standardize
rewindInstancegRPC error detection to usee instanceof Error && "code" in e. - Add Jest coverage to validate
causepreservation and wrapping behavior for key gRPC status codes.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/durabletask-js/src/client/client.ts | Preserves original gRPC error as cause when rethrowing user-friendly errors in rewind/restart operations. |
| packages/durabletask-js/test/client-error-cause.spec.ts | Adds tests ensuring wrapped errors preserve cause and unrecognized gRPC errors are rethrown unchanged. |
| package-lock.json | Lockfile metadata update (removal of several "peer": true entries). |
| } | ||
| if (grpcError.code === grpc.status.CANCELLED) { | ||
| throw new Error(`The rewind operation for '${instanceId}' was cancelled.`); | ||
| throw new Error(`The rewind operation for '${instanceId}' was cancelled.`, { cause: e }); |
There was a problem hiding this comment.
In this file, cancellation is spelled both as "canceled" (e.g., restartOrchestration/getOrchestrationHistory) and "cancelled" (rewindInstance). Since these are user-facing error messages, please standardize on a single spelling for consistency (and update the corresponding test expectation).
| throw new Error(`The rewind operation for '${instanceId}' was cancelled.`, { cause: e }); | |
| throw new Error(`The rewind operation for '${instanceId}' was canceled.`, { cause: e }); |
Fixes #185
Problem
rewindInstance and restartOrchestration in TaskHubGrpcClient catch gRPC errors and rethrow new Error objects with user-friendly messages, but discard the original error. Users cannot access the original gRPC ServiceError details (metadata, status details, stack trace).
Changes