( queueName: string, /* * Only the fields the span attributes read — keeps full BullMQ jobs * assignable while letting tests pass a structural stub without casts. */ job: Pick<Job, "id" | "name" | "attemptsMade">, handler: () => Promise<T> )
| 24 | * sees the failure exactly as it did before. |
| 25 | */ |
| 26 | export const withQueueSpan = async <T>( |
| 27 | queueName: string, |
| 28 | /* |
| 29 | * Only the fields the span attributes read — keeps full BullMQ jobs |
| 30 | * assignable while letting tests pass a structural stub without casts. |
| 31 | */ |
| 32 | job: Pick<Job, "id" | "name" | "attemptsMade">, |
| 33 | handler: () => Promise<T> |
| 34 | ): Promise<T> => |
| 35 | tracer.startActiveSpan( |
| 36 | `queue.${queueName}.process`, |
| 37 | { |
| 38 | attributes: { |
| 39 | "messaging.system": "bullmq", |
| 40 | "messaging.destination.name": queueName, |
| 41 | "messaging.message.id": job.id ?? "", |
| 42 | "messaging.bullmq.job.name": job.name, |
| 43 | "messaging.bullmq.job.attempt": job.attemptsMade + 1, |
| 44 | }, |
| 45 | }, |
| 46 | async (span) => { |
| 47 | try { |
| 48 | const result = await handler(); |
| 49 | |
| 50 | span.setStatus({ code: SpanStatusCode.OK }); |
| 51 | |
| 52 | return result; |
| 53 | } catch (error) { |
| 54 | span.setStatus({ |
| 55 | code: SpanStatusCode.ERROR, |
| 56 | message: getErrorMessage(error), |
| 57 | }); |
| 58 | |
| 59 | if (error instanceof Error) { |
| 60 | span.recordException(error); |
| 61 | } |
| 62 | |
| 63 | throw error; |
| 64 | } finally { |
| 65 | span.end(); |
| 66 | } |
| 67 | } |
| 68 | ); |
no test coverage detected