(this: { executed?: boolean }, ...args: unknown[])
| 218 | // IMPORTANT: We must replace the handle function directly, not use a Proxy, |
| 219 | // because Query.then() internally calls this.handle(), which would bypass a Proxy wrapper. |
| 220 | const wrappedHandle = async function (this: { executed?: boolean }, ...args: unknown[]): Promise<unknown> { |
| 221 | // postgres.js calls handle() from then/catch/finally — only the first call executes SQL, |
| 222 | // subsequent calls are no-ops (guarded by this.executed). Skip span creation for no-ops. |
| 223 | if (this.executed || !_shouldCreateSpans(options)) { |
| 224 | return originalHandle.apply(this, args); |
| 225 | } |
| 226 | |
| 227 | const fullQuery = _reconstructQuery(query.strings); |
| 228 | const sanitizedSqlQuery = _sanitizeSqlQuery(fullQuery); |
| 229 | |
| 230 | return startSpanManual( |
| 231 | { |
| 232 | name: sanitizedSqlQuery || 'postgresjs.query', |
| 233 | op: 'db', |
| 234 | }, |
| 235 | (span: Span) => { |
| 236 | span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.postgresjs'); |
| 237 | |
| 238 | span.setAttributes({ |
| 239 | 'db.system.name': 'postgres', |
| 240 | 'db.query.text': sanitizedSqlQuery, |
| 241 | }); |
| 242 | |
| 243 | const connectionContext = sqlInstance |
| 244 | ? ((sqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as |
| 245 | | PostgresConnectionContext |
| 246 | | undefined) |
| 247 | : undefined; |
| 248 | |
| 249 | _setConnectionAttributes(span, connectionContext); |
| 250 | |
| 251 | if (options.requestHook) { |
| 252 | try { |
| 253 | options.requestHook(span, sanitizedSqlQuery, connectionContext); |
| 254 | } catch (e) { |
| 255 | span.setAttribute('sentry.hook.error', 'requestHook failed'); |
| 256 | DEBUG_BUILD && debug.error('Error in requestHook for PostgresJs instrumentation:', e); |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | const queryWithCallbacks = this as { |
| 261 | resolve: unknown; |
| 262 | reject: unknown; |
| 263 | }; |
| 264 | |
| 265 | queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve as (...args: unknown[]) => unknown, { |
| 266 | apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => { |
| 267 | try { |
| 268 | _setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command); |
| 269 | span.end(); |
| 270 | } catch (e) { |
| 271 | DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e); |
| 272 | } |
| 273 | |
| 274 | return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs); |
| 275 | }, |
| 276 | }); |
| 277 |
nothing calls this directly
no test coverage detected