import { Span , SpanAttributes , SpanStatusCode , Tracer , } from '@opentelemetry/api' ; import { spanRequestSymbol } from './constants' ; import type { PluginFastifyReply } from './types' ; param reply param tracer param spanName param spanAttributes export function startSpan ( reply , tracer , spanName , spanAttributes = { } ) { const span = tracer . startSpan ( spanName , { attributes : spanAttributes } ) ; const spans = reply [ spanRequestSymbol ] || [ ] ; spans . push ( span ) ; Object . defineProperty ( reply , spanRequestSymbol , { enumerable : false , configurable : true , value : spans , } ) ; return span ; } param reply param err export function endSpan ( reply , err ? ) { const spans = reply [ spanRequestSymbol ] || [ ] ; if ( ! spans . length ) { return ; } spans . forEach ( span => { if ( err ) { span . setStatus ( { code : SpanStatusCode . ERROR , message : err . message , } ) ; span . recordException ( err ) ; } span . end ( ) ; } ) ; delete reply [ spanRequestSymbol ] ; } param execute param onFinish param preventThrowingError export function safeExecuteInTheMiddleMaybePromise < T > ( execute , onFinish , preventThrowingError ? ) ; export function safeExecuteInTheMiddleMaybePromise < T > ( execute , onFinish , preventThrowingError ? ) ; export function safeExecuteInTheMiddleMaybePromise < T > ( execute , onFinish , preventThrowingError ? ) { let error ; let result = undefined ; try { result = execute ( ) ; if ( isPromise ( result ) ) { result . then ( res => onFinish ( undefined , res ) , err => onFinish ( err ) ) ; } } catch ( e ) { error = e ; } finally { if ( ! isPromise ( result ) ) { onFinish ( error , result ) ; if ( error && ! preventThrowingError ) { throw error ; } } return result ; } } function isPromise < T > ( val ) { return ( ( typeof val === 'object' && val && typeof Object . getOwnPropertyDescriptor ( val , 'then' ) ?. value === 'function' ) || false ) ; }