7
7
type Subscription ,
8
8
type Trigger ,
9
9
} from './types' ;
10
+ import { setTimeout } from 'node:timers/promises' ;
11
+ import { serializeError } from 'serialize-error' ;
10
12
11
13
const log = Logger . child ( {
12
14
namespace : 'subscribe' ,
@@ -67,11 +69,21 @@ const runTask = async ({
67
69
68
70
let attempt = - 1 ;
69
71
70
- while ( attempt ++ < trigger . retry . retries ) {
71
- const retriesLeft = trigger . retry . retries - attempt ;
72
+ while ( true ) {
73
+ attempt ++ ;
72
74
73
- if ( retriesLeft < 0 ) {
74
- throw new Error ( 'Expected retries left to be greater than or equal to 0' ) ;
75
+ if ( attempt > 0 ) {
76
+ const retryFactor = trigger . retry . factor ?? 2 ;
77
+ const minTimeout = trigger . retry . minTimeout ?? 1_000 ;
78
+ const maxTimeout = trigger . retry . maxTimeout ?? 30_000 ;
79
+ const delay = Math . min (
80
+ attempt * retryFactor * minTimeout ,
81
+ trigger . retry . maxTimeout ?? maxTimeout ,
82
+ ) ;
83
+
84
+ log . debug ( 'delaying retry by %dms...' , delay ) ;
85
+
86
+ await setTimeout ( delay ) ;
75
87
}
76
88
77
89
try {
@@ -92,13 +104,40 @@ const runTask = async ({
92
104
} ) ,
93
105
taskId,
94
106
} ) ;
107
+
108
+ return ;
95
109
} catch ( error ) {
96
110
if ( error . name === 'AbortError' ) {
97
111
log . warn ( '%s (%s): task aborted' , trigger . name , taskId ) ;
98
112
99
113
return ;
100
114
}
101
115
116
+ log . warn (
117
+ {
118
+ error : serializeError ( error ) ,
119
+ } ,
120
+ 'routine produced an error' ,
121
+ ) ;
122
+
123
+ if ( trigger . persistent ) {
124
+ log . warn (
125
+ '%s (%s): retrying because the trigger is persistent' ,
126
+ trigger . name ,
127
+ taskId ,
128
+ ) ;
129
+
130
+ continue ;
131
+ }
132
+
133
+ const retriesLeft = trigger . retry . retries - attempt ;
134
+
135
+ if ( retriesLeft < 0 ) {
136
+ throw new Error (
137
+ 'Expected retries left to be greater than or equal to 0' ,
138
+ ) ;
139
+ }
140
+
102
141
if ( retriesLeft === 0 ) {
103
142
log . warn (
104
143
'%s (%s): task will not be retried; attempts exhausted' ,
@@ -229,8 +268,15 @@ export const subscribe = (trigger: Trigger): Subscription => {
229
268
}
230
269
} )
231
270
// eslint-disable-next-line promise/prefer-await-to-then
232
- . catch ( ( ) => {
233
- log . warn ( '%s (%s): task failed' , trigger . name , taskId ) ;
271
+ . catch ( ( error ) => {
272
+ log . warn (
273
+ {
274
+ error : serializeError ( error ) ,
275
+ } ,
276
+ '%s (%s): task failed' ,
277
+ trigger . name ,
278
+ taskId ,
279
+ ) ;
234
280
} ) ;
235
281
236
282
log . debug ( '%s (%s): started task' , trigger . name , taskId ) ;
0 commit comments