@@ -136,48 +136,44 @@ function moveHistory(changeType) {
136
136
}
137
137
138
138
function unwrapIfNotMulti ( paths , idProps , spec , anyVals , depType ) {
139
+ let msg = '' ;
140
+
139
141
if ( isMultiValued ( spec ) ) {
140
- return idProps ;
142
+ return [ idProps , msg ] ;
141
143
}
144
+
142
145
if ( idProps . length !== 1 ) {
143
146
if ( ! idProps . length ) {
144
- if ( typeof spec . id === 'string' ) {
145
- throw new ReferenceError (
146
- 'A nonexistent object was used in an `' +
147
- depType +
148
- '` of a Dash callback. The id of this object is `' +
149
- spec . id +
150
- '` and the property is `' +
151
- spec . property +
152
- '`. The string ids in the current layout are: [' +
153
- keys ( paths . strs ) . join ( ', ' ) +
154
- ']'
155
- ) ;
156
- }
157
- throw new ReferenceError (
147
+ const isStr = typeof spec . id === 'string' ;
148
+ msg =
158
149
'A nonexistent object was used in an `' +
159
- depType +
160
- '` of a Dash callback. The id of this object is ' +
161
- JSON . stringify ( spec . id ) +
162
- ( anyVals ? ' with MATCH values ' + anyVals : '' ) +
163
- ' and the property is `' +
164
- spec . property +
165
- '`. The wildcard ids currently available are logged above.'
166
- ) ;
167
- }
168
- throw new ReferenceError (
169
- 'Multiple objects were found for an `' +
150
+ depType +
151
+ '` of a Dash callback. The id of this object is ' +
152
+ ( isStr
153
+ ? '`' + spec . id + '`'
154
+ : JSON . stringify ( spec . id ) +
155
+ ( anyVals ? ' with MATCH values ' + anyVals : '' ) ) +
156
+ ' and the property is `' +
157
+ spec . property +
158
+ ( isStr
159
+ ? '`. The string ids in the current layout are: [' +
160
+ keys ( paths . strs ) . join ( ', ' ) +
161
+ ']'
162
+ : '`. The wildcard ids currently available are logged above.' ) ;
163
+ } else {
164
+ msg =
165
+ 'Multiple objects were found for an `' +
170
166
depType +
171
167
'` of a callback that only takes one value. The id spec is ' +
172
168
JSON . stringify ( spec . id ) +
173
169
( anyVals ? ' with MATCH values ' + anyVals : '' ) +
174
170
' and the property is `' +
175
171
spec . property +
176
172
'`. The objects we found are: ' +
177
- JSON . stringify ( map ( pick ( [ 'id' , 'property' ] ) , idProps ) )
178
- ) ;
173
+ JSON . stringify ( map ( pick ( [ 'id' , 'property' ] ) , idProps ) ) ;
174
+ }
179
175
}
180
- return idProps [ 0 ] ;
176
+ return [ idProps [ 0 ] , msg ] ;
181
177
}
182
178
183
179
function startCallbacks ( callbacks ) {
@@ -259,26 +255,30 @@ async function fireReadyCallbacks(dispatch, getState, callbacks) {
259
255
return preventCallback ( ) ;
260
256
}
261
257
262
- let outputs ;
263
- try {
264
- outputs = allOutputs . map ( ( out , i ) =>
265
- unwrapIfNotMulti (
266
- paths ,
267
- map ( pick ( [ 'id' , 'property' ] ) , out ) ,
268
- cb . callback . outputs [ i ] ,
269
- cb . anyVals ,
270
- 'Output'
271
- )
258
+ const outputs = [ ] ;
259
+ const outputErrors = [ ] ;
260
+ allOutputs . forEach ( ( out , i ) => {
261
+ const [ outi , erri ] = unwrapIfNotMulti (
262
+ paths ,
263
+ map ( pick ( [ 'id' , 'property' ] ) , out ) ,
264
+ cb . callback . outputs [ i ] ,
265
+ cb . anyVals ,
266
+ 'Output'
272
267
) ;
273
- } catch ( e ) {
274
- if ( e instanceof ReferenceError && ! flatten ( inVals ) . length ) {
275
- // This case is all-empty multivalued wildcard inputs,
276
- // which we would normally fire the callback for, except
277
- // some outputs are missing. So instead we treat it like
278
- // regular missing inputs and just silently prevent it.
279
- return preventCallback ( ) ;
268
+ outputs . push ( outi ) ;
269
+ if ( erri ) {
270
+ outputErrors . push ( erri ) ;
280
271
}
281
- throw e ;
272
+ } ) ;
273
+ if ( outputErrors . length ) {
274
+ if ( flatten ( inVals ) . length ) {
275
+ refErr ( outputErrors , paths ) ;
276
+ }
277
+ // This case is all-empty multivalued wildcard inputs,
278
+ // which we would normally fire the callback for, except
279
+ // some outputs are missing. So instead we treat it like
280
+ // regular missing inputs and just silently prevent it.
281
+ return preventCallback ( ) ;
282
282
}
283
283
284
284
payload = {
@@ -431,8 +431,8 @@ function fillVals(paths, layout, cb, specs, depType, allowAllMissing) {
431
431
const errors = [ ] ;
432
432
let emptyMultiValues = 0 ;
433
433
434
- const fillInputs = ( inputList , i ) =>
435
- unwrapIfNotMulti (
434
+ const inputVals = getter ( paths ) . map ( ( inputList , i ) => {
435
+ const [ inputs , inputError ] = unwrapIfNotMulti (
436
436
paths ,
437
437
inputList . map ( ( { id, property, path : path_ } ) => ( {
438
438
id,
@@ -443,44 +443,44 @@ function fillVals(paths, layout, cb, specs, depType, allowAllMissing) {
443
443
cb . anyVals ,
444
444
depType
445
445
) ;
446
-
447
- const tryFill = ( inputList , i ) => {
448
- try {
449
- const inputs = fillInputs ( inputList , i ) ;
450
- if ( isMultiValued ( specs [ i ] ) && ! inputs . length ) {
451
- emptyMultiValues ++ ;
452
- }
453
- return inputs ;
454
- } catch ( e ) {
455
- if ( e instanceof ReferenceError ) {
456
- errors . push ( e ) ;
457
- return null ;
458
- }
459
- // any other error we still want to see!
460
- throw e ;
446
+ if ( isMultiValued ( specs [ i ] ) && ! inputs . length ) {
447
+ emptyMultiValues ++ ;
461
448
}
462
- } ;
463
-
464
- const inputVals = getter ( paths ) . map ( allowAllMissing ? tryFill : fillInputs ) ;
449
+ if ( inputError ) {
450
+ errors . push ( inputError ) ;
451
+ }
452
+ return inputs ;
453
+ } ) ;
465
454
466
455
if ( errors . length ) {
467
- if ( errors . length + emptyMultiValues === inputVals . length ) {
456
+ if (
457
+ allowAllMissing &&
458
+ errors . length + emptyMultiValues === inputVals . length
459
+ ) {
468
460
// We have at least one non-multivalued input, but all simple and
469
461
// multi-valued inputs are missing.
470
462
// (if all inputs are multivalued and all missing we still return
471
463
// them as normal, and fire the callback.)
472
464
return null ;
473
465
}
474
466
// If we get here we have some missing and some present inputs.
475
- // That's a real error, so rethrow the first missing error.
467
+ // Or all missing in a context that doesn't allow this.
468
+ // That's a real problem, so throw the first message as an error.
469
+ refErr ( errors , paths ) ;
470
+ }
471
+
472
+ return inputVals ;
473
+ }
474
+
475
+ function refErr ( errors , paths ) {
476
+ const err = errors [ 0 ] ;
477
+ if ( err . indexOf ( 'logged above' ) !== - 1 ) {
476
478
// Wildcard reference errors mention a list of wildcard specs logged
477
479
// TODO: unwrapped list of wildcard ids?
478
480
// eslint-disable-next-line no-console
479
481
console . error ( paths . objs ) ;
480
- throw errors [ 0 ] ;
481
482
}
482
-
483
- return inputVals ;
483
+ throw new ReferenceError ( err ) ;
484
484
}
485
485
486
486
function handleServerside ( config , payload , hooks ) {
0 commit comments