@@ -409,6 +409,25 @@ export class CopilotKitCore {
409409 ) ;
410410 }
411411
412+ /**
413+ * Log a message to the console and emit an error to subscribers.
414+ * Catches failures from `emitError` itself to prevent unhandled rejections.
415+ */
416+ private logAndEmitError (
417+ message : string ,
418+ params : {
419+ error : Error ;
420+ code : CopilotKitCoreErrorCode ;
421+ context ?: Record < string , any > ;
422+ } ,
423+ logLevel : "error" | "warn" = "error" ,
424+ ) : void {
425+ console [ logLevel ] ( message , params . error ) ;
426+ this . emitError ( params ) . catch ( ( emitErr : unknown ) => {
427+ console . error ( message + " — emitError itself failed:" , emitErr ) ;
428+ } ) ;
429+ }
430+
412431 /**
413432 * Snapshot accessors
414433 */
@@ -474,22 +493,17 @@ export class CopilotKitCore {
474493 */
475494 setDefaultThrottleMs ( value : number | undefined ) : void {
476495 if ( value !== undefined && ( ! Number . isFinite ( value ) || value < 0 ) ) {
477- console . error (
496+ this . logAndEmitError (
478497 `CopilotKitCore.setDefaultThrottleMs: value must be a non-negative finite number or undefined, ` +
479498 `got ${ value } . Keeping current value (${ this . _defaultThrottleMs } ).` ,
499+ {
500+ error : new Error (
501+ `setDefaultThrottleMs: invalid value (${ value } ), keeping current value (${ this . _defaultThrottleMs } )` ,
502+ ) ,
503+ code : CopilotKitCoreErrorCode . SUBSCRIBER_CALLBACK_FAILED ,
504+ context : { value, currentValue : this . _defaultThrottleMs } ,
505+ } ,
480506 ) ;
481- this . emitError ( {
482- error : new Error (
483- `setDefaultThrottleMs: invalid value (${ value } ), keeping current value (${ this . _defaultThrottleMs } )` ,
484- ) ,
485- code : CopilotKitCoreErrorCode . SUBSCRIBER_CALLBACK_FAILED ,
486- context : { value, currentValue : this . _defaultThrottleMs } ,
487- } ) . catch ( ( emitErr : unknown ) => {
488- console . error (
489- `CopilotKitCore.setDefaultThrottleMs: emitError itself failed:` ,
490- emitErr ,
491- ) ;
492- } ) ;
493507 return ;
494508 }
495509 this . _defaultThrottleMs = value ;
@@ -677,22 +691,17 @@ export class CopilotKitCore {
677691 if ( ! Number . isFinite ( resolved ) || resolved < 0 ) {
678692 const source =
679693 options ?. throttleMs !== undefined ? "throttleMs" : "defaultThrottleMs" ;
680- console . error (
694+ this . logAndEmitError (
681695 `CopilotKitCore.subscribeToAgentWithOptions: ${ source } must be a non-negative finite number, ` +
682696 `got ${ resolved } . Falling back to unthrottled.` ,
697+ {
698+ error : new Error (
699+ `subscribeToAgentWithOptions: invalid ${ source } (${ resolved } ), falling back to unthrottled` ,
700+ ) ,
701+ code : CopilotKitCoreErrorCode . SUBSCRIBER_CALLBACK_FAILED ,
702+ context : { agentId : agent . agentId , source, value : resolved } ,
703+ } ,
683704 ) ;
684- this . emitError ( {
685- error : new Error (
686- `subscribeToAgentWithOptions: invalid ${ source } (${ resolved } ), falling back to unthrottled` ,
687- ) ,
688- code : CopilotKitCoreErrorCode . SUBSCRIBER_CALLBACK_FAILED ,
689- context : { agentId : agent . agentId , source, value : resolved } ,
690- } ) . catch ( ( emitErr : unknown ) => {
691- console . error (
692- `CopilotKitCore.subscribeToAgentWithOptions[${ agent . agentId || "(unknown agent)" } ]: emitError itself failed:` ,
693- emitErr ,
694- ) ;
695- } ) ;
696705 } else {
697706 effectiveMs = resolved ;
698707 }
@@ -709,18 +718,14 @@ export class CopilotKitCore {
709718 ...args : Parameters < F >
710719 ) : any => {
711720 const reportError = ( err : unknown , verb : string ) => {
712- const message = `CopilotKitCore.subscribeToAgentWithOptions[${ agentLabel } ]: ${ label } callback ${ verb } :` ;
713- console . error ( message , err ) ;
714- this . emitError ( {
715- error : err instanceof Error ? err : new Error ( String ( err ) ) ,
716- code : CopilotKitCoreErrorCode . SUBSCRIBER_CALLBACK_FAILED ,
717- context : { agentId : agent . agentId , callback : label } ,
718- } ) . catch ( ( emitErr : unknown ) => {
719- console . error (
720- `CopilotKitCore.subscribeToAgentWithOptions[${ agentLabel } ]: emitError itself failed:` ,
721- emitErr ,
722- ) ;
723- } ) ;
721+ this . logAndEmitError (
722+ `CopilotKitCore.subscribeToAgentWithOptions[${ agentLabel } ]: ${ label } callback ${ verb } :` ,
723+ {
724+ error : err instanceof Error ? err : new Error ( String ( err ) ) ,
725+ code : CopilotKitCoreErrorCode . SUBSCRIBER_CALLBACK_FAILED ,
726+ context : { agentId : agent . agentId , callback : label } ,
727+ } ,
728+ ) ;
724729 } ;
725730 try {
726731 const result = fn ( ...args ) ;
@@ -781,17 +786,15 @@ export class CopilotKitCore {
781786 `CopilotKitCore.subscribeToAgentWithOptions[${ agentLabel } ]: callback "${ key } " is not supported ` +
782787 `and was dropped. Supported callbacks: ${ Array . from ( ALLOWED_KEYS ) . join ( ", " ) } . ` +
783788 `Use agent.subscribe() directly for event handlers and per-item notifications.` ;
784- console . warn ( message ) ;
785- this . emitError ( {
786- error : new Error ( message ) ,
787- code : CopilotKitCoreErrorCode . SUBSCRIBER_CALLBACK_FAILED ,
788- context : { agentId : agent . agentId , droppedCallback : key } ,
789- } ) . catch ( ( emitErr : unknown ) => {
790- console . error (
791- `CopilotKitCore.subscribeToAgentWithOptions[${ agentLabel } ]: emitError itself failed:` ,
792- emitErr ,
793- ) ;
794- } ) ;
789+ this . logAndEmitError (
790+ message ,
791+ {
792+ error : new Error ( message ) ,
793+ code : CopilotKitCoreErrorCode . SUBSCRIBER_CALLBACK_FAILED ,
794+ context : { agentId : agent . agentId , droppedCallback : key } ,
795+ } ,
796+ "warn" ,
797+ ) ;
795798 }
796799 }
797800
0 commit comments