@@ -2,6 +2,7 @@ import { SpanKind } from "@opentelemetry/api";
22import { SerializableJson } from "@trigger.dev/core" ;
33import {
44 accessoryAttributes ,
5+ ApiError ,
56 apiClientManager ,
67 ApiRequestOptions ,
78 conditionallyImportPacket ,
@@ -17,6 +18,7 @@ import {
1718 parsePacket ,
1819 Queue ,
1920 QueueOptions ,
21+ RateLimitError ,
2022 resourceCatalog ,
2123 runtime ,
2224 SemanticInternalAttributes ,
@@ -125,9 +127,6 @@ export { SubtaskUnwrapError, TaskRunPromise };
125127
126128export type Context = TaskRunContext ;
127129
128- // Re-export for external use (defined later in file)
129- export { BatchTriggerError } ;
130-
131130export function queue ( options : QueueOptions ) : Queue {
132131 resourceCatalog . registerQueueMetadata ( options ) ;
133132
@@ -1592,12 +1591,28 @@ async function executeBatchTwoPhase(
15921591/**
15931592 * Error thrown when batch trigger operations fail.
15941593 * Includes context about which phase failed and the batch details.
1594+ *
1595+ * When the underlying error is a rate limit (429), additional properties are exposed:
1596+ * - `isRateLimited`: true
1597+ * - `retryAfterMs`: milliseconds until the rate limit resets
15951598 */
1596- class BatchTriggerError extends Error {
1599+ export class BatchTriggerError extends Error {
15971600 readonly phase : "create" | "stream" ;
15981601 readonly batchId ?: string ;
15991602 readonly itemCount : number ;
16001603
1604+ /** True if the error was caused by rate limiting (HTTP 429) */
1605+ readonly isRateLimited : boolean ;
1606+
1607+ /** Milliseconds until the rate limit resets. Only set when `isRateLimited` is true. */
1608+ readonly retryAfterMs ?: number ;
1609+
1610+ /** The underlying API error, if the cause was an ApiError */
1611+ readonly apiError ?: ApiError ;
1612+
1613+ /** The underlying cause of the error */
1614+ override readonly cause ?: unknown ;
1615+
16011616 constructor (
16021617 message : string ,
16031618 options : {
@@ -1607,12 +1622,59 @@ class BatchTriggerError extends Error {
16071622 itemCount : number ;
16081623 }
16091624 ) {
1610- super ( message , { cause : options . cause } ) ;
1625+ // Build enhanced message that includes the cause's message
1626+ const fullMessage = buildBatchErrorMessage ( message , options . cause ) ;
1627+ super ( fullMessage , { cause : options . cause } ) ;
1628+
16111629 this . name = "BatchTriggerError" ;
1630+ this . cause = options . cause ;
16121631 this . phase = options . phase ;
16131632 this . batchId = options . batchId ;
16141633 this . itemCount = options . itemCount ;
1634+
1635+ // Extract rate limit info from cause
1636+ if ( options . cause instanceof RateLimitError ) {
1637+ this . isRateLimited = true ;
1638+ this . retryAfterMs = options . cause . millisecondsUntilReset ;
1639+ this . apiError = options . cause ;
1640+ } else if ( options . cause instanceof ApiError ) {
1641+ this . isRateLimited = options . cause . status === 429 ;
1642+ this . apiError = options . cause ;
1643+ } else {
1644+ this . isRateLimited = false ;
1645+ }
1646+ }
1647+ }
1648+
1649+ /**
1650+ * Build an enhanced error message that includes context from the cause.
1651+ */
1652+ function buildBatchErrorMessage ( baseMessage : string , cause : unknown ) : string {
1653+ if ( ! cause ) {
1654+ return baseMessage ;
1655+ }
1656+
1657+ // Handle RateLimitError specifically for better messaging
1658+ if ( cause instanceof RateLimitError ) {
1659+ const retryMs = cause . millisecondsUntilReset ;
1660+ if ( retryMs !== undefined ) {
1661+ const retrySeconds = Math . ceil ( retryMs / 1000 ) ;
1662+ return `${ baseMessage } : Rate limit exceeded - retry after ${ retrySeconds } s` ;
1663+ }
1664+ return `${ baseMessage } : Rate limit exceeded` ;
16151665 }
1666+
1667+ // Handle other ApiErrors
1668+ if ( cause instanceof ApiError ) {
1669+ return `${ baseMessage } : ${ cause . message } ` ;
1670+ }
1671+
1672+ // Handle generic errors
1673+ if ( cause instanceof Error ) {
1674+ return `${ baseMessage } : ${ cause . message } ` ;
1675+ }
1676+
1677+ return baseMessage ;
16161678}
16171679
16181680/**
0 commit comments