Setting the file. One moment.
Multi Step Attempt · Wix Replatform · wix/skills · Skills Docs
ContentsBack to the top of the page lib/multi-step-attempt.js
lib/ multi-step-attempt.js
JavaScript · 94 lines · 5 KB
14 // writeAttempted: false -> failed_retryable (the writer stopped before its create)
15 // requestSent: false -> failed_retryable (refused before the network; nothing written)
16 // outcomeKnown: false -> succeeded_unverified (the reply was lost: read back, never resend blind)
17 // 4xx other than 408/429 -> failed_terminal (the target refused this body)
18 // anything else -> failed_retryable (429, 408, 5xx, a read that could not decide)
19 //
20 // Pure: it decides the row's status, targetId, findings and failure; the caller journals them.
21
22 const RETRYABLE_4XX = new Set ([ 408 , 429 ]);
23 const AUTH_EXPIRED_REASON = 'auth_expired' ;
24
25 function requireString ( value , label ) {
26 if ( typeof value !== 'string' || value === '' ) throw new Error ( `${ label } must be a nonempty string` );
27 return value;
28 }
29
30 function baseFailureOutcome ( error , { writeAttempted = true } = {}) {
31 if ( ! writeAttempted) return 'failed_retryable' ;
32 if (error && error.requestSent === false ) return 'failed_retryable' ;
33 if (error && (error.authExpired === true || error.reason === AUTH_EXPIRED_REASON || error.code === AUTH_EXPIRED_REASON )) return 'failed_retryable' ;
34 if (error && error.outcomeKnown === false ) return 'unresolved' ;
35 const status = error && Number. isInteger (error.status) ? error.status : null ;
36 if (status !== null && status >= 400 && status < 500 && ! RETRYABLE_4XX . has (status)) return 'failed_terminal' ;
37 return 'failed_retryable' ;
38 }
39
40 const STATUS_FOR_OUTCOME = Object. freeze ({
41 failed_retryable: 'failed_retryable' ,
42 failed_terminal: 'failed_terminal' ,
43 unresolved: 'succeeded_unverified' ,
44 });
45
46 // base: { targetId, outcome, error, intendedTargetId, writeAttempted } -- targetId only when the target holds it
47 // subSteps: [{ stage, outcome, failed, error }] -- ignored unless the base exists
48 function classifyMultiStepAttempt ({ sourceStableKey , operation , base , subSteps = [], findings = [] } = {}) {
49 requireString (sourceStableKey, 'sourceStableKey' );
50 requireString (operation, 'operation' );
51 if ( ! base || typeof base !== 'object' ) throw new Error ( 'base must describe the base record step' );
52 requireString (base.outcome, 'base.outcome' );
53 if ( ! Array. isArray (subSteps)) throw new Error ( 'subSteps must be an array' );
54 const rowFindings = [ ... findings];
55
56 if (base.targetId) {
57 for ( const step of subSteps) {
58 if ( ! step || ! step.failed) continue ;
59 rowFindings. push ({
60 code: 'sub-step-failed' ,
61 stage: requireString (step.stage, 'subSteps[].stage' ),
62 outcome: requireString (step.outcome, 'subSteps[].outcome' ),
63 retryable: true ,
64 ... (step.error && step.error.status ? { httpStatus: step.error.status } : {}),
65 });
66 }
67 return { status: 'imported' , targetId: String (base.targetId), findings: rowFindings, failure: undefined };
68 }
69
70 const error = base.error || null ;
71 const outcome = baseFailureOutcome (error, { writeAttempted: base.writeAttempted !== false });
72 const status = Number. isInteger (error && error.status) ? error.status : null ;
73 const authExpired = Boolean (error && (error.authExpired === true || error.reason === AUTH_EXPIRED_REASON || error.code === AUTH_EXPIRED_REASON ));
74 return {
75 status: STATUS_FOR_OUTCOME [outcome],
76 targetId: undefined ,
77 findings: rowFindings,
78 failure: {
79 sourceId: sourceStableKey,
80 targetEntityId: null ,
81 ... (base.intendedTargetId ? { intendedTargetId: String (base.intendedTargetId) } : {}),
82 operation,
83 httpStatus: status,
84 errorCode: authExpired ? AUTH_EXPIRED_REASON : (error && (error.applicationErrorCode || error.code)) || base.outcome,
85 scopeGroupName: null ,
86 outcome,
87 message: String ((error && error.message) || base.outcome). slice ( 0 , 300 ),
88 ... (authExpired ? { reason: AUTH_EXPIRED_REASON } : {}),
89 ... (error && error.requestSent === false ? { requestSent: false } : {}),
90 },
91 };
92 }
93
94 module . exports = { classifyMultiStepAttempt, baseFailureOutcome };