@@ -279,60 +279,50 @@ function getRun<ValueType, EntitiesType>(
279
279
return decision ;
280
280
}
281
281
282
- // fall back to defaultValue if it is set,
283
- let decisionPromise : Promise < ValueType > | ValueType ;
284
- try {
285
- decisionPromise = Promise . resolve < ValueType > (
286
- decide ( {
287
- headers : readonlyHeaders ,
288
- cookies : readonlyCookies ,
289
- entities,
290
- } ) ,
291
- )
292
- // catch errors in async "decide" functions
293
- . then < ValueType , ValueType > (
294
- ( value ) => {
295
- if ( value !== undefined ) return value ;
296
- if ( definition . defaultValue !== undefined )
297
- return definition . defaultValue ;
298
- throw new Error (
299
- `@vercel/flags: Flag "${ definition . key } " must have a defaultValue or a decide function that returns a value` ,
300
- ) ;
301
- } ,
302
- ( error : Error ) => {
303
- if ( isInternalNextError ( error ) ) throw error ;
304
-
305
- // try to recover if defaultValue is set
306
- if ( definition . defaultValue !== undefined ) {
282
+ // We use an async iife to ensure we can catch both sync and async errors of
283
+ // the original decide function, as that one is not guaranted to be async.
284
+ //
285
+ // Also fall back to defaultValue when the decide function returns undefined or throws an error.
286
+ const decisionPromise = ( async ( ) => {
287
+ return decide ( {
288
+ headers : readonlyHeaders ,
289
+ cookies : readonlyCookies ,
290
+ entities,
291
+ } ) ;
292
+ } ) ( )
293
+ // catch errors in async "decide" functions
294
+ . then < ValueType , ValueType > (
295
+ ( value ) => {
296
+ if ( value !== undefined ) return value ;
297
+ if ( definition . defaultValue !== undefined )
298
+ return definition . defaultValue ;
299
+ throw new Error (
300
+ `@vercel/flags: Flag "${ definition . key } " must have a defaultValue or a decide function that returns a value` ,
301
+ ) ;
302
+ } ,
303
+ ( error : Error ) => {
304
+ if ( isInternalNextError ( error ) ) throw error ;
305
+
306
+ // try to recover if defaultValue is set
307
+ if ( definition . defaultValue !== undefined ) {
308
+ if ( process . env . NODE_ENV === 'development' ) {
309
+ console . info (
310
+ `@vercel/flags: Flag "${ definition . key } " is falling back to its defaultValue` ,
311
+ ) ;
312
+ } else {
307
313
console . warn (
308
- `@vercel/flags: Flag "${ definition . key } " is falling back to the defaultValue after catching the following error` ,
314
+ `@vercel/flags: Flag "${ definition . key } " is falling back to its defaultValue after catching the following error` ,
309
315
error ,
310
316
) ;
311
- return definition . defaultValue ;
312
317
}
313
- console . warn (
314
- `@vercel/flags: Flag "${ definition . key } " could not be evaluated` ,
315
- ) ;
316
- throw error ;
317
- } ,
318
- ) ;
319
- } catch ( error ) {
320
- if ( isInternalNextError ( error ) ) throw error ;
321
-
322
- // catch errors in sync "decide" functions
323
- if ( definition . defaultValue !== undefined ) {
324
- console . warn (
325
- `@vercel/flags: Flag "${ definition . key } " is falling back to the defaultValue after catching the following error` ,
326
- error ,
327
- ) ;
328
- decisionPromise = Promise . resolve ( definition . defaultValue ) ;
329
- } else {
330
- console . warn (
331
- `@vercel/flags: Flag "${ definition . key } " could not be evaluated` ,
332
- ) ;
333
- throw error ;
334
- }
335
- }
318
+ return definition . defaultValue ;
319
+ }
320
+ console . warn (
321
+ `@vercel/flags: Flag "${ definition . key } " could not be evaluated` ,
322
+ ) ;
323
+ throw error ;
324
+ } ,
325
+ ) ;
336
326
337
327
setCachedValuePromise (
338
328
readonlyHeaders ,
0 commit comments