@@ -3,6 +3,7 @@ import type { ReactElement } from "react";
3
3
import { createQueryPreloader } from "../createQueryPreloader" ;
4
4
import {
5
5
ApolloClient ,
6
+ ApolloError ,
6
7
ApolloLink ,
7
8
InMemoryCache ,
8
9
NetworkStatus ,
@@ -14,6 +15,7 @@ import { expectTypeOf } from "expect-type";
14
15
import { QueryReference } from "../../cache/QueryReference" ;
15
16
import { DeepPartial , Observable } from "../../../utilities" ;
16
17
import {
18
+ Profiler ,
17
19
SimpleCaseData ,
18
20
VariablesCaseData ,
19
21
createProfiler ,
@@ -25,6 +27,8 @@ import {
25
27
import { ApolloProvider } from "../../context" ;
26
28
import { RenderOptions , render } from "@testing-library/react" ;
27
29
import { UseReadQueryResult , useReadQuery } from "../../hooks" ;
30
+ import { GraphQLError } from "graphql" ;
31
+ import { ErrorBoundary } from "react-error-boundary" ;
28
32
29
33
function createDefaultClient ( mocks : MockedResponse [ ] ) {
30
34
return new ApolloClient ( {
@@ -49,6 +53,31 @@ function renderWithClient(
49
53
} ) ;
50
54
}
51
55
56
+ function createDefaultProfiledComponents <
57
+ Snapshot extends {
58
+ result : UseReadQueryResult < any > | null ;
59
+ } ,
60
+ TData = Snapshot [ "result" ] extends UseReadQueryResult < infer TData > | null ?
61
+ TData
62
+ : unknown ,
63
+ > ( profiler : Profiler < Snapshot > , queryRef : QueryReference < TData > ) {
64
+ function SuspenseFallback ( ) {
65
+ useTrackRenders ( ) ;
66
+ return < p > Loading</ p > ;
67
+ }
68
+
69
+ function ReadQueryHook ( ) {
70
+ useTrackRenders ( ) ;
71
+ profiler . mergeSnapshot ( {
72
+ result : useReadQuery ( queryRef ) ,
73
+ } as Partial < Snapshot > ) ;
74
+
75
+ return null ;
76
+ }
77
+
78
+ return { SuspenseFallback, ReadQueryHook } ;
79
+ }
80
+
52
81
test ( "loads a query and suspends when passed to useReadQuery" , async ( ) => {
53
82
const { query, mocks } = useSimpleCase ( ) ;
54
83
const client = createDefaultClient ( mocks ) ;
@@ -303,6 +332,67 @@ test("can handle cache updates", async () => {
303
332
dispose ( ) ;
304
333
} ) ;
305
334
335
+ test ( "throws when error is returned" , async ( ) => {
336
+ // Disable error messages shown by React when an error is thrown to an error
337
+ // boundary
338
+ using _consoleSpy = spyOnConsole ( "error" ) ;
339
+ const { query } = useSimpleCase ( ) ;
340
+ const mocks = [
341
+ { request : { query } , result : { errors : [ new GraphQLError ( "Oops" ) ] } } ,
342
+ ] ;
343
+ const client = createDefaultClient ( mocks ) ;
344
+ const Profiler = createProfiler ( {
345
+ initialSnapshot : {
346
+ result : null as UseReadQueryResult < SimpleCaseData > | null ,
347
+ error : null as Error | null ,
348
+ } ,
349
+ } ) ;
350
+
351
+ const preloadQuery = createQueryPreloader ( client ) ;
352
+ const [ queryRef , dispose ] = preloadQuery ( query ) ;
353
+
354
+ const { SuspenseFallback, ReadQueryHook } = createDefaultProfiledComponents (
355
+ Profiler ,
356
+ queryRef
357
+ ) ;
358
+
359
+ function ErrorFallback ( { error } : { error : Error } ) {
360
+ useTrackRenders ( ) ;
361
+ Profiler . mergeSnapshot ( { error } ) ;
362
+
363
+ return null ;
364
+ }
365
+
366
+ function App ( ) {
367
+ return (
368
+ < ErrorBoundary FallbackComponent = { ErrorFallback } >
369
+ < Suspense fallback = { < SuspenseFallback /> } >
370
+ < ReadQueryHook />
371
+ </ Suspense >
372
+ </ ErrorBoundary >
373
+ ) ;
374
+ }
375
+
376
+ renderWithClient ( < App /> , { client, wrapper : Profiler } ) ;
377
+
378
+ {
379
+ const { renderedComponents } = await Profiler . takeRender ( ) ;
380
+
381
+ expect ( renderedComponents ) . toStrictEqual ( [ SuspenseFallback ] ) ;
382
+ }
383
+
384
+ {
385
+ const { snapshot, renderedComponents } = await Profiler . takeRender ( ) ;
386
+
387
+ expect ( renderedComponents ) . toStrictEqual ( [ ErrorFallback ] ) ;
388
+ expect ( snapshot . error ) . toEqual (
389
+ new ApolloError ( { graphQLErrors : [ new GraphQLError ( "Oops" ) ] } )
390
+ ) ;
391
+ }
392
+
393
+ dispose ( ) ;
394
+ } ) ;
395
+
306
396
test ( "passes context to the link" , async ( ) => {
307
397
interface QueryData {
308
398
context : Record < string , any > ;
0 commit comments