@@ -28,6 +28,8 @@ import type {
28
28
QueryDefinition ,
29
29
ResultDescription ,
30
30
ResultTypeFrom ,
31
+ SchemaFailureHandler ,
32
+ SchemaFailureInfo ,
31
33
} from '../endpointDefinitions'
32
34
import {
33
35
calculateProvidedBy ,
@@ -65,6 +67,7 @@ import {
65
67
isRejectedWithValue ,
66
68
SHOULD_AUTOBATCH ,
67
69
} from './rtkImports'
70
+ import { parseWithSchema , NamedSchemaError } from '../standardSchema'
68
71
69
72
export type BuildThunksApiEndpointQuery <
70
73
Definition extends QueryDefinition < any , any , any , any , any > ,
@@ -329,6 +332,8 @@ export function buildThunks<
329
332
api,
330
333
assertTagType,
331
334
selectors,
335
+ onSchemaFailure,
336
+ skipSchemaValidation : globalSkipSchemaValidation ,
332
337
} : {
333
338
baseQuery : BaseQuery
334
339
reducerPath : ReducerPath
@@ -337,6 +342,8 @@ export function buildThunks<
337
342
api : Api < BaseQuery , Definitions , ReducerPath , any >
338
343
assertTagType : AssertTagTypes
339
344
selectors : AllSelectors
345
+ onSchemaFailure : SchemaFailureHandler | undefined
346
+ skipSchemaValidation : boolean | undefined
340
347
} ) {
341
348
type State = RootState < any , string , ReducerPath >
342
349
@@ -491,10 +498,14 @@ export function buildThunks<
491
498
} ,
492
499
) => {
493
500
const endpointDefinition = endpointDefinitions [ arg . endpointName ]
501
+ const { metaSchema, skipSchemaValidation = globalSkipSchemaValidation } =
502
+ endpointDefinition
494
503
495
504
try {
496
- let transformResponse : TransformCallback =
497
- getTransformCallbackForEndpoint ( endpointDefinition , 'transformResponse' )
505
+ let transformResponse = getTransformCallbackForEndpoint (
506
+ endpointDefinition ,
507
+ 'transformResponse' ,
508
+ )
498
509
499
510
const baseQueryApi = {
500
511
signal,
@@ -551,7 +562,16 @@ export function buildThunks<
551
562
finalQueryArg : unknown ,
552
563
) : Promise < QueryReturnValue > {
553
564
let result : QueryReturnValue
554
- const { extraOptions } = endpointDefinition
565
+ const { extraOptions, argSchema, rawResponseSchema, responseSchema } =
566
+ endpointDefinition
567
+
568
+ if ( argSchema && ! skipSchemaValidation ) {
569
+ finalQueryArg = await parseWithSchema (
570
+ argSchema ,
571
+ finalQueryArg ,
572
+ 'argSchema' ,
573
+ )
574
+ }
555
575
556
576
if ( forceQueryFn ) {
557
577
// upsertQueryData relies on this to pass in the user-provided value
@@ -606,13 +626,34 @@ export function buildThunks<
606
626
607
627
if ( result . error ) throw new HandledError ( result . error , result . meta )
608
628
609
- const transformedResponse = await transformResponse (
610
- result . data ,
629
+ let { data } = result
630
+
631
+ if ( rawResponseSchema && ! skipSchemaValidation ) {
632
+ data = await parseWithSchema (
633
+ rawResponseSchema ,
634
+ result . data ,
635
+ 'rawResponseSchema' ,
636
+ )
637
+ }
638
+
639
+ let transformedResponse = await transformResponse (
640
+ data ,
611
641
result . meta ,
612
642
finalQueryArg ,
613
643
)
614
644
615
- return { ...result , data : transformedResponse }
645
+ if ( responseSchema && ! skipSchemaValidation ) {
646
+ transformedResponse = await parseWithSchema (
647
+ responseSchema ,
648
+ transformedResponse ,
649
+ 'responseSchema' ,
650
+ )
651
+ }
652
+
653
+ return {
654
+ ...result ,
655
+ data : transformedResponse ,
656
+ }
616
657
}
617
658
618
659
if (
@@ -698,6 +739,14 @@ export function buildThunks<
698
739
finalQueryReturnValue = await executeRequest ( arg . originalArgs )
699
740
}
700
741
742
+ if ( metaSchema && ! skipSchemaValidation && finalQueryReturnValue . meta ) {
743
+ finalQueryReturnValue . meta = await parseWithSchema (
744
+ metaSchema ,
745
+ finalQueryReturnValue . meta ,
746
+ 'metaSchema' ,
747
+ )
748
+ }
749
+
701
750
// console.log('Final result: ', transformedData)
702
751
return fulfillWithValue (
703
752
finalQueryReturnValue . data ,
@@ -707,40 +756,78 @@ export function buildThunks<
707
756
} ) ,
708
757
)
709
758
} catch ( error ) {
710
- let catchedError = error
711
- if ( catchedError instanceof HandledError ) {
712
- let transformErrorResponse : TransformCallback =
713
- getTransformCallbackForEndpoint (
759
+ try {
760
+ let caughtError = error
761
+ if ( caughtError instanceof HandledError ) {
762
+ let transformErrorResponse = getTransformCallbackForEndpoint (
714
763
endpointDefinition ,
715
764
'transformErrorResponse' ,
716
765
)
766
+ const { rawErrorResponseSchema, errorResponseSchema } =
767
+ endpointDefinition
768
+
769
+ let { value, meta } = caughtError
770
+
771
+ if ( rawErrorResponseSchema && ! skipSchemaValidation ) {
772
+ value = await parseWithSchema (
773
+ rawErrorResponseSchema ,
774
+ value ,
775
+ 'rawErrorResponseSchema' ,
776
+ )
777
+ }
778
+
779
+ if ( metaSchema && ! skipSchemaValidation ) {
780
+ meta = await parseWithSchema ( metaSchema , meta , 'metaSchema' )
781
+ }
717
782
718
- try {
719
- return rejectWithValue (
720
- await transformErrorResponse (
721
- catchedError . value ,
722
- catchedError . meta ,
783
+ try {
784
+ let transformedErrorResponse = await transformErrorResponse (
785
+ value ,
786
+ meta ,
723
787
arg . originalArgs ,
724
- ) ,
725
- addShouldAutoBatch ( { baseQueryMeta : catchedError . meta } ) ,
726
- )
727
- } catch ( e ) {
728
- catchedError = e
788
+ )
789
+ if ( errorResponseSchema && ! skipSchemaValidation ) {
790
+ transformedErrorResponse = await parseWithSchema (
791
+ errorResponseSchema ,
792
+ transformedErrorResponse ,
793
+ 'errorResponseSchema' ,
794
+ )
795
+ }
796
+
797
+ return rejectWithValue (
798
+ transformedErrorResponse ,
799
+ addShouldAutoBatch ( { baseQueryMeta : meta } ) ,
800
+ )
801
+ } catch ( e ) {
802
+ caughtError = e
803
+ }
729
804
}
730
- }
731
- if (
732
- typeof process !== 'undefined' &&
733
- process . env . NODE_ENV !== 'production'
734
- ) {
735
- console . error (
736
- `An unhandled error occurred processing a request for the endpoint "${ arg . endpointName } ".
805
+ if (
806
+ typeof process !== 'undefined' &&
807
+ process . env . NODE_ENV !== 'production'
808
+ ) {
809
+ console . error (
810
+ `An unhandled error occurred processing a request for the endpoint "${ arg . endpointName } ".
737
811
In the case of an unhandled error, no tags will be "provided" or "invalidated".` ,
738
- catchedError ,
739
- )
740
- } else {
741
- console . error ( catchedError )
812
+ caughtError ,
813
+ )
814
+ } else {
815
+ console . error ( caughtError )
816
+ }
817
+ throw caughtError
818
+ } catch ( error ) {
819
+ if ( error instanceof NamedSchemaError ) {
820
+ const info : SchemaFailureInfo = {
821
+ endpoint : arg . endpointName ,
822
+ arg : arg . originalArgs ,
823
+ type : arg . type ,
824
+ queryCacheKey : arg . type === 'query' ? arg . queryCacheKey : undefined ,
825
+ }
826
+ endpointDefinition . onSchemaFailure ?.( error , info )
827
+ onSchemaFailure ?.( error , info )
828
+ }
829
+ throw error
742
830
}
743
- throw catchedError
744
831
}
745
832
}
746
833
0 commit comments