1- // safePushData : parse the Apify dataset schema-validation error, repair the
2- // offending items (strip bad fields, placeholder missing required ones), and
3- // retry the push.
1+ // pushDataWithSchemaRepair : parse the Apify dataset schema-validation error,
2+ // repair the offending items (strip bad fields, placeholder missing required
3+ // ones), and retry the push.
44//
55// NOTE: instead of recursively healing the data one error-round at a time, we
66// could parse the Actor's `dataset_schema.json` up front and fix every item in
@@ -61,7 +61,7 @@ export interface DroppedItem<T> {
6161
6262// Field names say what they hold: `*Count` is a number, `*Items` is an array
6363// of objects. `R` is whatever the caller's push function resolves to.
64- export interface SafePushDataResult < T , R = unknown > {
64+ export interface PushDataWithSchemaRepairResult < T , R = unknown > {
6565 /** How many of the caller's items made it into the dataset. */
6666 pushedCount : number ;
6767 /** The items we couldn't repair, each with the errors that doomed it. */
@@ -75,7 +75,7 @@ export interface SafePushDataResult<T, R = unknown> {
7575 pushResult ?: R ;
7676}
7777
78- export interface SafePushDataOptions {
78+ export interface PushDataWithSchemaRepairOptions {
7979 maxAttempts ?: number ;
8080}
8181
@@ -92,11 +92,11 @@ export type PushFn<T, R = unknown> = (items: T[]) => Promise<R>;
9292 *
9393 * Whatever `pushFn` resolves to is handed back untouched as `pushResult`.
9494 */
95- export async function safePushData < T , R = unknown > (
95+ export async function pushDataWithSchemaRepair < T , R = unknown > (
9696 pushFn : PushFn < T , R > ,
9797 input : T | T [ ] ,
98- options : SafePushDataOptions = { } ,
99- ) : Promise < SafePushDataResult < T , R > > {
98+ options : PushDataWithSchemaRepairOptions = { } ,
99+ ) : Promise < PushDataWithSchemaRepairResult < T , R > > {
100100 const items = Array . isArray ( input ) ? input : [ input ] ;
101101
102102 // Happy path: assume validation will succeed (the overwhelmingly common
@@ -118,7 +118,7 @@ async function cleanAndRetry<T, R>(
118118 originalItems : readonly T [ ] ,
119119 initialError : SchemaValidationError ,
120120 maxAttempts : number ,
121- ) : Promise < SafePushDataResult < T , R > > {
121+ ) : Promise < PushDataWithSchemaRepairResult < T , R > > {
122122 // working[i] is what we'll send on the next push. We mutate this array
123123 // in place (splicing drops, replacing cleaned entries); the caller's
124124 // `originalItems` is never touched.
@@ -155,7 +155,7 @@ async function cleanAndRetry<T, R>(
155155 // everything that isn't in it, so "original minus dropped" is exactly what
156156 // landed. (A rejected push stores nothing at all — not even the items the
157157 // API found no fault with.)
158- const result = ( attemptCount : number , pushResult ?: R ) : SafePushDataResult < T , R > => ( {
158+ const result = ( attemptCount : number , pushResult ?: R ) : PushDataWithSchemaRepairResult < T , R > => ( {
159159 pushedCount : originalItems . length - dropped . length ,
160160 droppedItems : dropped ,
161161 attemptCount,
@@ -182,7 +182,9 @@ async function cleanAndRetry<T, R>(
182182 // position outside the batch we actually sent) instead of
183183 // crashing on `working[i]` being undefined.
184184 if ( i < 0 || i >= working . length ) {
185- console . log ( `safePushData: ignoring out-of-range itemPosition ${ i } in validation error response.` ) ;
185+ console . log (
186+ `pushDataWithSchemaRepair: ignoring out-of-range itemPosition ${ i } in validation error response.` ,
187+ ) ;
186188 continue ;
187189 }
188190 const cleaned = cleanItemFields ( working [ i ] , invalid . validationErrors , placeholderPaths [ i ] ) ;
@@ -198,7 +200,7 @@ async function cleanAndRetry<T, R>(
198200 }
199201
200202 const report = [
201- `safePushData : schema validation failed on attempt ${ attempts } : ${ lastError . data . invalidItems . length } invalid item(s)` ,
203+ `pushDataWithSchemaRepair : schema validation failed on attempt ${ attempts } : ${ lastError . data . invalidItems . length } invalid item(s)` ,
202204 ] ;
203205 if ( repairedFields . size > 0 ) report . push ( `repaired fields: ${ formatFields ( repairedFields ) } ` ) ;
204206 if ( droppedThisRound > 0 ) {
@@ -227,7 +229,7 @@ async function cleanAndRetry<T, R>(
227229 unresolved ++ ;
228230 dropAt ( i , roundErrors [ i ] ) ;
229231 }
230- const giveUp = [ `safePushData : gave up after ${ maxAttempts } attempts` ] ;
232+ const giveUp = [ `pushDataWithSchemaRepair : gave up after ${ maxAttempts } attempts` ] ;
231233 if ( unresolved > 0 ) {
232234 giveUp . push ( `dropped ${ unresolved } item(s) still failing on fields: ${ formatFields ( unresolvedFields ) } ` ) ;
233235 }
@@ -249,7 +251,9 @@ async function cleanAndRetry<T, R>(
249251 for ( const invalid of err . data . invalidItems ) {
250252 errorsAt . set ( invalid . itemPosition , invalid . validationErrors ) ;
251253 }
252- console . log ( `safePushData: final push of ${ working . length } item(s) was rejected too; dropping them.` ) ;
254+ console . log (
255+ `pushDataWithSchemaRepair: final push of ${ working . length } item(s) was rejected too; dropping them.` ,
256+ ) ;
253257 for ( let i = working . length - 1 ; i >= 0 ; i -- ) dropAt ( i , errorsAt . get ( i ) ?? NO_ERRORS ) ;
254258 return result ( attempts ) ;
255259 }
0 commit comments