@@ -237,12 +237,10 @@ where
237
237
. as_ref ( )
238
238
. map_or ( false , |client| client. options ( ) . send_default_pii ) ;
239
239
240
- let ( mut tx, sentry_req) = sentry_request_from_http ( & req, with_pii) ;
240
+ let sentry_req = sentry_request_from_http ( & req, with_pii) ;
241
+ let name = transaction_name_from_http ( & req) ;
241
242
242
243
let transaction = if inner. start_transaction {
243
- let name = std:: mem:: take ( & mut tx)
244
- . unwrap_or_else ( || format ! ( "{} {}" , req. method( ) , req. uri( ) ) ) ;
245
-
246
244
let headers = req. headers ( ) . iter ( ) . flat_map ( |( header, value) | {
247
245
value. to_str ( ) . ok ( ) . map ( |value| ( header. as_str ( ) , value) )
248
246
} ) ;
@@ -262,7 +260,7 @@ where
262
260
if let Some ( transaction) = transaction. as_ref ( ) {
263
261
scope. set_span ( Some ( transaction. clone ( ) . into ( ) ) ) ;
264
262
} else {
265
- scope. set_transaction ( tx . as_deref ( ) ) ;
263
+ scope. set_transaction ( ( !inner . start_transaction ) . then_some ( & name ) ) ;
266
264
}
267
265
scope. add_event_processor ( move |event| Some ( process_event ( event, & sentry_req) ) ) ;
268
266
parent_span
@@ -336,14 +334,14 @@ fn map_status(status: StatusCode) -> protocol::SpanStatus {
336
334
}
337
335
}
338
336
339
- /// Build a Sentry request struct from the HTTP request
340
- fn sentry_request_from_http ( request : & ServiceRequest , with_pii : bool ) -> ( Option < String > , Request ) {
341
- let transaction = if let Some ( name) = request. match_name ( ) {
342
- Some ( String :: from ( name) )
343
- } else {
344
- request. match_pattern ( )
345
- } ;
337
+ /// Extract a transaction name from the HTTP request
338
+ fn transaction_name_from_http ( req : & ServiceRequest ) -> String {
339
+ let path_part = req. match_pattern ( ) . unwrap_or_else ( || "<none>" . to_string ( ) ) ;
340
+ format ! ( "{} {}" , req. method( ) , path_part)
341
+ }
346
342
343
+ /// Build a Sentry request struct from the HTTP request
344
+ fn sentry_request_from_http ( request : & ServiceRequest , with_pii : bool ) -> Request {
347
345
let mut sentry_req = Request {
348
346
url : format ! (
349
347
"{}://{}{}" ,
@@ -369,7 +367,7 @@ fn sentry_request_from_http(request: &ServiceRequest, with_pii: bool) -> (Option
369
367
}
370
368
} ;
371
369
372
- ( transaction , sentry_req)
370
+ sentry_req
373
371
}
374
372
375
373
/// Add request data to a Sentry event
@@ -451,13 +449,56 @@ mod tests {
451
449
assert_eq ! ( events. len( ) , 2 ) ;
452
450
for event in events {
453
451
let request = event. request . expect ( "Request should be set." ) ;
454
- assert_eq ! ( event. transaction, Some ( "/test" . into( ) ) ) ;
452
+ assert_eq ! ( event. transaction, Some ( "GET /test" . into( ) ) ) ;
455
453
assert_eq ! ( event. message, Some ( "Message" . into( ) ) ) ;
456
454
assert_eq ! ( event. level, Level :: Warning ) ;
457
455
assert_eq ! ( request. method, Some ( "GET" . into( ) ) ) ;
458
456
}
459
457
}
460
458
459
+ /// Test transaction name HTTP verb.
460
+ #[ actix_web:: test]
461
+ async fn test_match_pattern ( ) {
462
+ let events = sentry:: test:: with_captured_events ( || {
463
+ block_on ( async {
464
+ let service = |_name : String | {
465
+ // Current Hub should have no events
466
+ _assert_hub_no_events ( ) ;
467
+
468
+ sentry:: capture_message ( "Message" , Level :: Warning ) ;
469
+
470
+ // Current Hub should have the event
471
+ _assert_hub_has_events ( ) ;
472
+
473
+ HttpResponse :: Ok ( )
474
+ } ;
475
+
476
+ let app = init_service (
477
+ App :: new ( )
478
+ . wrap ( Sentry :: builder ( ) . with_hub ( Hub :: current ( ) ) . finish ( ) )
479
+ . service ( web:: resource ( "/test/{name}" ) . route ( web:: post ( ) . to ( service) ) ) ,
480
+ )
481
+ . await ;
482
+
483
+ // Call the service twice (sequentially) to ensure the middleware isn't sticky
484
+ for _ in 0 ..2 {
485
+ let req = TestRequest :: post ( ) . uri ( "/test/fake_name" ) . to_request ( ) ;
486
+ let res = call_service ( & app, req) . await ;
487
+ assert ! ( res. status( ) . is_success( ) ) ;
488
+ }
489
+ } )
490
+ } ) ;
491
+
492
+ assert_eq ! ( events. len( ) , 2 ) ;
493
+ for event in events {
494
+ let request = event. request . expect ( "Request should be set." ) ;
495
+ assert_eq ! ( event. transaction, Some ( "POST /test/{name}" . into( ) ) ) ;
496
+ assert_eq ! ( event. message, Some ( "Message" . into( ) ) ) ;
497
+ assert_eq ! ( event. level, Level :: Warning ) ;
498
+ assert_eq ! ( request. method, Some ( "POST" . into( ) ) ) ;
499
+ }
500
+ }
501
+
461
502
/// Ensures errors returned in the Actix service trigger an event.
462
503
#[ actix_web:: test]
463
504
async fn test_response_errors ( ) {
@@ -490,7 +531,7 @@ mod tests {
490
531
assert_eq ! ( events. len( ) , 2 ) ;
491
532
for event in events {
492
533
let request = event. request . expect ( "Request should be set." ) ;
493
- assert_eq ! ( event. transaction, Some ( "failing " . into( ) ) ) ; // Transaction name is the name of the function
534
+ assert_eq ! ( event. transaction, Some ( "GET /test " . into( ) ) ) ; // Transaction name is the matcher of the route
494
535
assert_eq ! ( event. message, None ) ;
495
536
assert_eq ! ( event. exception. values[ 0 ] . ty, String :: from( "Custom" ) ) ;
496
537
assert_eq ! ( event. exception. values[ 0 ] . value, Some ( "Test Error" . into( ) ) ) ;
0 commit comments