1- import { EventProcessor , Hub , Integration } from '@sentry/types' ;
1+ import { Integration , Transaction } from '@sentry/types' ;
22import { logger } from '@sentry/utils' ;
33// tslint:disable-next-line:no-implicit-dependencies
44import { Application , ErrorRequestHandler , NextFunction , Request , RequestHandler , Response } from 'express' ;
55
6+ /**
7+ * Internal helper for `__sentry_transaction`
8+ * @hidden
9+ */
10+ interface SentryTracingResponse {
11+ __sentry_transaction ?: Transaction ;
12+ }
13+
614/**
715 * Express integration
816 *
@@ -35,12 +43,12 @@ export class Express implements Integration {
3543 /**
3644 * @inheritDoc
3745 */
38- public setupOnce ( _addGlobalEventProcessor : ( callback : EventProcessor ) => void , getCurrentHub : ( ) => Hub ) : void {
46+ public setupOnce ( ) : void {
3947 if ( ! this . _app ) {
4048 logger . error ( 'ExpressIntegration is missing an Express instance' ) ;
4149 return ;
4250 }
43- instrumentMiddlewares ( this . _app , getCurrentHub ) ;
51+ instrumentMiddlewares ( this . _app ) ;
4452 }
4553}
4654
@@ -56,40 +64,66 @@ export class Express implements Integration {
5664 * // error handler
5765 * app.use(function (err, req, res, next) { ... })
5866 */
59- function wrap ( fn : Function , getCurrentHub : ( ) => Hub ) : RequestHandler | ErrorRequestHandler {
67+ function wrap ( fn : Function ) : RequestHandler | ErrorRequestHandler {
6068 const arrity = fn . length ;
6169
6270 switch ( arrity ) {
6371 case 2 : {
64- return function ( this : NodeJS . Global , _req : Request , res : Response ) : any {
65- const span = getCurrentHub ( ) . startSpan ( {
66- description : fn . name ,
67- op : 'middleware' ,
68- } ) ;
69- res . once ( 'finish' , ( ) => span . finish ( ) ) ;
72+ return function ( this : NodeJS . Global , _req : Request , res : Response & SentryTracingResponse ) : any {
73+ const transaction = res . __sentry_transaction ;
74+ if ( transaction ) {
75+ const span = transaction . startChild ( {
76+ description : fn . name ,
77+ op : 'middleware' ,
78+ } ) ;
79+ res . once ( 'finish' , ( ) => {
80+ span . finish ( ) ;
81+ } ) ;
82+ }
7083 return fn . apply ( this , arguments ) ;
7184 } ;
7285 }
7386 case 3 : {
74- return function ( this : NodeJS . Global , req : Request , res : Response , next : NextFunction ) : any {
75- const span = getCurrentHub ( ) . startSpan ( {
76- description : fn . name ,
77- op : 'middleware' ,
78- } ) ;
87+ return function (
88+ this : NodeJS . Global ,
89+ req : Request ,
90+ res : Response & SentryTracingResponse ,
91+ next : NextFunction ,
92+ ) : any {
93+ const transaction = res . __sentry_transaction ;
94+ const span =
95+ transaction &&
96+ transaction . startChild ( {
97+ description : fn . name ,
98+ op : 'middleware' ,
99+ } ) ;
79100 fn . call ( this , req , res , function ( this : NodeJS . Global ) : any {
80- span . finish ( ) ;
101+ if ( span ) {
102+ span . finish ( ) ;
103+ }
81104 return next . apply ( this , arguments ) ;
82105 } ) ;
83106 } ;
84107 }
85108 case 4 : {
86- return function ( this : NodeJS . Global , err : any , req : Request , res : Response , next : NextFunction ) : any {
87- const span = getCurrentHub ( ) . startSpan ( {
88- description : fn . name ,
89- op : 'middleware' ,
90- } ) ;
109+ return function (
110+ this : NodeJS . Global ,
111+ err : any ,
112+ req : Request ,
113+ res : Response & SentryTracingResponse ,
114+ next : NextFunction ,
115+ ) : any {
116+ const transaction = res . __sentry_transaction ;
117+ const span =
118+ transaction &&
119+ transaction . startChild ( {
120+ description : fn . name ,
121+ op : 'middleware' ,
122+ } ) ;
91123 fn . call ( this , err , req , res , function ( this : NodeJS . Global ) : any {
92- span . finish ( ) ;
124+ if ( span ) {
125+ span . finish ( ) ;
126+ }
93127 return next . apply ( this , arguments ) ;
94128 } ) ;
95129 } ;
@@ -110,16 +144,16 @@ function wrap(fn: Function, getCurrentHub: () => Hub): RequestHandler | ErrorReq
110144 * app.use([<path>], <fn>, ...<fn>)
111145 * app.use([<path>], ...<fn>[])
112146 */
113- function wrapUseArgs ( args : IArguments , getCurrentHub : ( ) => Hub ) : unknown [ ] {
147+ function wrapUseArgs ( args : IArguments ) : unknown [ ] {
114148 return Array . from ( args ) . map ( ( arg : unknown ) => {
115149 if ( typeof arg === 'function' ) {
116- return wrap ( arg , getCurrentHub ) ;
150+ return wrap ( arg ) ;
117151 }
118152
119153 if ( Array . isArray ( arg ) ) {
120154 return arg . map ( ( a : unknown ) => {
121155 if ( typeof a === 'function' ) {
122- return wrap ( a , getCurrentHub ) ;
156+ return wrap ( a ) ;
123157 }
124158 return a ;
125159 } ) ;
@@ -132,10 +166,10 @@ function wrapUseArgs(args: IArguments, getCurrentHub: () => Hub): unknown[] {
132166/**
133167 * Patches original app.use to utilize our tracing functionality
134168 */
135- function instrumentMiddlewares ( app : Application , getCurrentHub : ( ) => Hub ) : Application {
169+ function instrumentMiddlewares ( app : Application ) : Application {
136170 const originalAppUse = app . use ;
137171 app . use = function ( ) : any {
138- return originalAppUse . apply ( this , wrapUseArgs ( arguments , getCurrentHub ) ) ;
172+ return originalAppUse . apply ( this , wrapUseArgs ( arguments ) ) ;
139173 } ;
140174 return app ;
141175}
0 commit comments