@@ -15,21 +15,30 @@ const MAX_STACK_FRAMES = 50;
1515 * detects whether each frame is user code (in_app: true) or library code (in_app: false).
1616 *
1717 * @param error - The error to capture (can be Error, string, object, or any value)
18+ * @param contextStack - Optional Error object to use for stack context (for validation errors)
1819 * @returns ErrorData object with structured error information
1920 */
20- export function captureException ( error : unknown ) : ErrorData {
21+ export function captureException (
22+ error : unknown ,
23+ contextStack ?: Error ,
24+ ) : ErrorData {
25+ // Handle CallToolResult objects (SDK 1.21.0+ converts errors to these)
26+ if ( isCallToolResult ( error ) ) {
27+ return captureCallToolResultError ( error , contextStack ) ;
28+ }
29+
2130 // Handle non-Error objects
2231 if ( ! ( error instanceof Error ) ) {
2332 return {
2433 message : stringifyNonError ( error ) ,
25- type : "NonError" ,
34+ type : undefined ,
2635 platform : "javascript" ,
2736 } ;
2837 }
2938
3039 const errorData : ErrorData = {
3140 message : error . message || "" ,
32- type : error . name || error . constructor ?. name || "Error" ,
41+ type : error . name || error . constructor ?. name || undefined ,
3342 platform : "javascript" ,
3443 } ;
3544
@@ -677,7 +686,7 @@ function unwrapErrorCauses(error: Error): ChainedErrorData[] {
677686 if ( ! ( currentError instanceof Error ) ) {
678687 chainedErrors . push ( {
679688 message : stringifyNonError ( currentError ) ,
680- type : "NonError " ,
689+ type : "UnknownErrorType " ,
681690 } ) ;
682691 break ;
683692 }
@@ -708,6 +717,57 @@ function unwrapErrorCauses(error: Error): ChainedErrorData[] {
708717 return chainedErrors ;
709718}
710719
720+ /**
721+ * Detects if a value is a CallToolResult object (SDK 1.21.0+ error format).
722+ *
723+ * SDK 1.21.0+ converts errors to CallToolResult format:
724+ * { content: [{ type: "text", text: "error message" }], isError: true }
725+ *
726+ * @param value - Value to check
727+ * @returns True if value is a CallToolResult object
728+ */
729+ function isCallToolResult ( value : unknown ) : boolean {
730+ return (
731+ value !== null &&
732+ typeof value === "object" &&
733+ "isError" in value &&
734+ "content" in value &&
735+ Array . isArray ( ( value as any ) . content )
736+ ) ;
737+ }
738+
739+ /**
740+ * Extracts error information from CallToolResult objects.
741+ *
742+ * SDK 1.21.0+ converts errors to CallToolResult, losing original stack traces.
743+ * This extracts the error message from the content array.
744+ *
745+ * @param result - CallToolResult object with error
746+ * @param _contextStack - Optional Error object for stack context (unused, kept for compatibility)
747+ * @returns ErrorData with extracted message (no stack trace)
748+ */
749+ function captureCallToolResultError (
750+ result : any ,
751+ _contextStack ?: Error ,
752+ ) : ErrorData {
753+ // Extract message from content array
754+ const message =
755+ result . content
756+ ?. filter ( ( c : any ) => c . type === "text" )
757+ . map ( ( c : any ) => c . text )
758+ . join ( " " )
759+ . trim ( ) || "Unknown error" ;
760+
761+ const errorData : ErrorData = {
762+ message,
763+ type : "UnknownErrorType" , // Can't determine actual type from CallToolResult
764+ platform : "javascript" ,
765+ // No stack or frames - SDK stripped the original error information
766+ } ;
767+
768+ return errorData ;
769+ }
770+
711771/**
712772 * Converts non-Error objects to string representation for error messages.
713773 *
0 commit comments