@@ -515,6 +515,142 @@ describe("ClaudeCodeHandler", () => {
515515 await expect ( iterator . next ( ) ) . rejects . toThrow ( )
516516 } )
517517
518+ test ( "should suppress verbose 5-hour usage limit errors" , async ( ) => {
519+ const systemPrompt = "You are a helpful assistant"
520+ const messages = [ { role : "user" as const , content : "Hello" } ]
521+
522+ // Mock async generator that yields a 5-hour usage limit error
523+ const mockGenerator = async function * ( ) : AsyncGenerator < ClaudeCodeMessage | string > {
524+ yield {
525+ type : "assistant" as const ,
526+ message : {
527+ id : "msg_123" ,
528+ type : "message" ,
529+ role : "assistant" ,
530+ model : "claude-3-5-sonnet-20241022" ,
531+ content : [
532+ {
533+ type : "text" ,
534+ text : 'API Error: 429 {"error":{"message":"Usage limit reached. Please wait 5 hours before trying again."}}' ,
535+ } ,
536+ ] ,
537+ stop_reason : "stop_sequence" ,
538+ stop_sequence : null ,
539+ usage : {
540+ input_tokens : 10 ,
541+ output_tokens : 20 ,
542+ } ,
543+ } as any ,
544+ session_id : "session_123" ,
545+ }
546+ }
547+
548+ mockRunClaudeCode . mockReturnValue ( mockGenerator ( ) )
549+
550+ const stream = handler . createMessage ( systemPrompt , messages )
551+ const results = [ ]
552+
553+ // Should not throw an error - the error should be suppressed
554+ for await ( const chunk of stream ) {
555+ results . push ( chunk )
556+ }
557+
558+ // Should have no results since the error was suppressed
559+ expect ( results ) . toHaveLength ( 0 )
560+ } )
561+
562+ test ( "should suppress various 5-hour limit error messages" , async ( ) => {
563+ const systemPrompt = "You are a helpful assistant"
564+ const messages = [ { role : "user" as const , content : "Hello" } ]
565+
566+ const errorMessages = [
567+ 'API Error: 429 {"error":{"message":"5-hour usage limit exceeded"}}' ,
568+ 'API Error: 429 {"error":{"message":"Five hour rate limit reached"}}' ,
569+ 'API Error: 429 {"error":{"message":"Rate limit: Please wait before making another request"}}' ,
570+ 'API Error: 429 {"error":{"message":"Usage limit has been reached for this period"}}' ,
571+ ]
572+
573+ for ( const errorMessage of errorMessages ) {
574+ // Mock async generator that yields the error
575+ const mockGenerator = async function * ( ) : AsyncGenerator < ClaudeCodeMessage | string > {
576+ yield {
577+ type : "assistant" as const ,
578+ message : {
579+ id : "msg_123" ,
580+ type : "message" ,
581+ role : "assistant" ,
582+ model : "claude-3-5-sonnet-20241022" ,
583+ content : [
584+ {
585+ type : "text" ,
586+ text : errorMessage ,
587+ } ,
588+ ] ,
589+ stop_reason : "stop_sequence" ,
590+ stop_sequence : null ,
591+ usage : {
592+ input_tokens : 10 ,
593+ output_tokens : 20 ,
594+ } ,
595+ } as any ,
596+ session_id : "session_123" ,
597+ }
598+ }
599+
600+ mockRunClaudeCode . mockReturnValue ( mockGenerator ( ) )
601+
602+ const stream = handler . createMessage ( systemPrompt , messages )
603+ const results = [ ]
604+
605+ // Should not throw an error - the error should be suppressed
606+ for await ( const chunk of stream ) {
607+ results . push ( chunk )
608+ }
609+
610+ // Should have no results since the error was suppressed
611+ expect ( results ) . toHaveLength ( 0 )
612+ }
613+ } )
614+
615+ test ( "should not suppress non-429 API errors" , async ( ) => {
616+ const systemPrompt = "You are a helpful assistant"
617+ const messages = [ { role : "user" as const , content : "Hello" } ]
618+
619+ // Mock async generator that yields a non-429 error
620+ const mockGenerator = async function * ( ) : AsyncGenerator < ClaudeCodeMessage | string > {
621+ yield {
622+ type : "assistant" as const ,
623+ message : {
624+ id : "msg_123" ,
625+ type : "message" ,
626+ role : "assistant" ,
627+ model : "claude-3-5-sonnet-20241022" ,
628+ content : [
629+ {
630+ type : "text" ,
631+ text : 'API Error: 500 {"error":{"message":"Internal server error"}}' ,
632+ } ,
633+ ] ,
634+ stop_reason : "stop_sequence" ,
635+ stop_sequence : null ,
636+ usage : {
637+ input_tokens : 10 ,
638+ output_tokens : 20 ,
639+ } ,
640+ } as any ,
641+ session_id : "session_123" ,
642+ }
643+ }
644+
645+ mockRunClaudeCode . mockReturnValue ( mockGenerator ( ) )
646+
647+ const stream = handler . createMessage ( systemPrompt , messages )
648+ const iterator = stream [ Symbol . asyncIterator ] ( )
649+
650+ // Should throw an error for non-429 errors
651+ await expect ( iterator . next ( ) ) . rejects . toThrow ( '{"error":{"message":"Internal server error"}}' )
652+ } )
653+
518654 test ( "should log warning for unsupported tool_use content" , async ( ) => {
519655 const systemPrompt = "You are a helpful assistant"
520656 const messages = [ { role : "user" as const , content : "Hello" } ]
0 commit comments