File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -88,6 +88,13 @@ describe("error helpers", () => {
8888 expect ( formatted ) . toBe ( "error A | error B" ) ;
8989 } ) ;
9090
91+ it ( "dedupes repeated cause messages while preserving deeper distinct causes" , ( ) => {
92+ const rootCause = new Error ( "provider auth lookup failed" ) ;
93+ const inner = new Error ( 'No API key found for provider "openai-codex".' , { cause : rootCause } ) ;
94+ const wrapper = new Error ( inner . message , { cause : inner } ) ;
95+ expect ( formatErrorMessage ( wrapper ) ) . toBe ( `${ inner . message } | ${ rootCause . message } ` ) ;
96+ } ) ;
97+
9198 it ( "redacts sensitive tokens from formatted error messages" , ( ) => {
9299 const token = "sk-abcdefghijklmnopqrstuv" ;
93100 const formatted = formatErrorMessage ( new Error ( `Authorization: Bearer ${ token } ` ) ) ;
Original file line number Diff line number Diff line change @@ -72,15 +72,22 @@ export function formatErrorMessage(err: unknown): string {
7272 // Traverse .cause chain to include nested error messages (e.g. grammY HttpError wraps network errors in .cause)
7373 let cause : unknown = err . cause ;
7474 const seen = new Set < unknown > ( [ err ] ) ;
75+ // Skip causes that repeat a message already emitted (e.g. coerceToFailoverError).
76+ const seenMessages = new Set < string > ( [ formatted ] ) ;
77+ const appendCauseMessage = ( message : string ) : void => {
78+ if ( ! message || seenMessages . has ( message ) ) {
79+ return ;
80+ }
81+ formatted += ` | ${ message } ` ;
82+ seenMessages . add ( message ) ;
83+ } ;
7584 while ( cause && ! seen . has ( cause ) ) {
7685 seen . add ( cause ) ;
7786 if ( cause instanceof Error ) {
78- if ( cause . message ) {
79- formatted += ` | ${ cause . message } ` ;
80- }
87+ appendCauseMessage ( cause . message ) ;
8188 cause = cause . cause ;
8289 } else if ( typeof cause === "string" ) {
83- formatted += ` | ${ cause } ` ;
90+ appendCauseMessage ( cause ) ;
8491 break ;
8592 } else {
8693 break ;
You can’t perform that action at this time.
0 commit comments