11import  type  {  Client ,  IntegrationFn ,  SeverityLevel ,  Span  }  from  '@sentry/core' ; 
2- import  {  captureException ,  consoleSandbox ,  defineIntegration ,  getClient ,  withActiveSpan  }  from  '@sentry/core' ; 
2+ import  { 
3+   captureException , 
4+   consoleSandbox , 
5+   defineIntegration , 
6+   getClient , 
7+   isMatchingPattern , 
8+   withActiveSpan , 
9+ }  from  '@sentry/core' ; 
310import  {  logAndExitProcess  }  from  '../utils/errorhandling' ; 
411
512type  UnhandledRejectionMode  =  'none'  |  'warn'  |  'strict' ; 
613
14+ type  IgnoreMatcher  =  {  name ?: string  |  RegExp ;  message ?: string  |  RegExp  } ; 
15+ 
716interface  OnUnhandledRejectionOptions  { 
817  /** 
918   * Option deciding what to do after capturing unhandledRejection, 
1019   * that mimicks behavior of node's --unhandled-rejection flag. 
1120   */ 
1221  mode : UnhandledRejectionMode ; 
22+   /** Rejection Errors to ignore (don't capture or warn). */ 
23+   ignore ?: IgnoreMatcher [ ] ; 
1324} 
1425
1526const  INTEGRATION_NAME  =  'OnUnhandledRejection' ; 
1627
28+ const  DEFAULT_IGNORES : IgnoreMatcher [ ]  =  [ 
29+   { 
30+     name : 'AI_NoOutputGeneratedError' ,  // When stream aborts in Vercel AI SDK, Vercel flush() fails with an error 
31+   } , 
32+ ] ; 
33+ 
1734const  _onUnhandledRejectionIntegration  =  ( ( options : Partial < OnUnhandledRejectionOptions >  =  { } )  =>  { 
18-   const  opts  =  { 
19-     mode : 'warn' , 
20-     ...options , 
21-   }   satisfies   OnUnhandledRejectionOptions ; 
35+   const  opts :  OnUnhandledRejectionOptions  =  { 
36+     mode : options . mode   ??   'warn' , 
37+     ignore :  [ ...DEFAULT_IGNORES ,  ... ( options . ignore   ??   [ ] ) ] , 
38+   } ; 
2239
2340  return  { 
2441    name : INTEGRATION_NAME , 
@@ -28,27 +45,54 @@ const _onUnhandledRejectionIntegration = ((options: Partial<OnUnhandledRejection
2845  } ; 
2946} )  satisfies  IntegrationFn ; 
3047
31- /** 
32-  * Add a global promise rejection handler. 
33-  */ 
3448export  const  onUnhandledRejectionIntegration  =  defineIntegration ( _onUnhandledRejectionIntegration ) ; 
3549
36- /** 
37-  * Send an exception with reason 
38-  * @param  reason string 
39-  * @param  promise promise 
40-  * 
41-  * Exported only for tests. 
42-  */ 
50+ /** Extract error info safely */ 
51+ function  extractErrorInfo ( reason : unknown ) : {  name : string ;  message : string  }  { 
52+   // Check if reason is an object (including Error instances, not just plain objects) 
53+   if  ( typeof  reason  !==  'object'  ||  reason  ===  null )  { 
54+     return  {  name : '' ,  message : String ( reason  ??  '' )  } ; 
55+   } 
56+ 
57+   const  errorLike  =  reason  as  Record < string ,  unknown > ; 
58+   const  name  =  typeof  errorLike . name  ===  'string'  ? errorLike . name  : '' ; 
59+   const  message  =  typeof  errorLike . message  ===  'string'  ? errorLike . message  : String ( reason ) ; 
60+ 
61+   return  {  name,  message } ; 
62+ } 
63+ 
64+ /** Check if a matcher matches the reason */ 
65+ function  isMatchingReason ( matcher : IgnoreMatcher ,  errorInfo : ReturnType < typeof  extractErrorInfo > ) : boolean  { 
66+   // name/message matcher 
67+   const  nameMatches  =  matcher . name  ===  undefined  ||  isMatchingPattern ( errorInfo . name ,  matcher . name ,  true ) ; 
68+ 
69+   const  messageMatches  =  matcher . message  ===  undefined  ||  isMatchingPattern ( errorInfo . message ,  matcher . message ) ; 
70+ 
71+   return  nameMatches  &&  messageMatches ; 
72+ } 
73+ 
74+ /** Match helper */ 
75+ function  matchesIgnore ( list : IgnoreMatcher [ ] ,  reason : unknown ) : boolean  { 
76+   const  errorInfo  =  extractErrorInfo ( reason ) ; 
77+   return  list . some ( matcher  =>  isMatchingReason ( matcher ,  errorInfo ) ) ; 
78+ } 
79+ 
80+ /** Core handler */ 
4381export  function  makeUnhandledPromiseHandler ( 
4482  client : Client , 
4583  options : OnUnhandledRejectionOptions , 
4684) : ( reason : unknown ,  promise : unknown )  =>  void { 
4785  return  function  sendUnhandledPromise ( reason : unknown ,  promise : unknown ) : void { 
86+     // Only handle for the active client 
4887    if  ( getClient ( )  !==  client )  { 
4988      return ; 
5089    } 
5190
91+     // Skip if configured to ignore 
92+     if  ( matchesIgnore ( options . ignore  ??  [ ] ,  reason ) )  { 
93+       return ; 
94+     } 
95+ 
5296    const  level : SeverityLevel  =  options . mode  ===  'strict'  ? 'fatal'  : 'error' ; 
5397
5498    // this can be set in places where we cannot reliably get access to the active span/error 
0 commit comments