@@ -72,15 +72,40 @@ const useGraphQlApi = ({ initialPeriodsToLoad = DOCUMENT_LIST_SHARDS_PER_DAY * 2
7272 client . graphql ( { query : getDocument , variables : { objectKey } } ) ,
7373 ) ;
7474 const getDocumentResolutions = await Promise . allSettled ( getDocumentPromises ) ;
75+
76+ // Separate rejected promises from null/undefined results
7577 const getDocumentRejected = getDocumentResolutions . filter ( ( r ) => r . status === 'rejected' ) ;
76- if ( getDocumentRejected . length ) {
78+ const fulfilledResults = getDocumentResolutions . filter ( ( r ) => r . status === 'fulfilled' ) ;
79+ const getDocumentNull = fulfilledResults
80+ . map ( ( r , idx ) => ( { doc : r . value ?. data ?. getDocument , key : objectKeys [ idx ] } ) )
81+ . filter ( ( item ) => ! item . doc )
82+ . map ( ( item ) => item . key ) ;
83+
84+ // Only show error banner if ALL documents failed
85+ if ( getDocumentRejected . length === objectKeys . length ) {
7786 setErrorMessage ( 'failed to get document details - please try again later' ) ;
78- logger . error ( 'get document promises rejected' , getDocumentRejected ) ;
87+ logger . error ( 'All document queries rejected' , getDocumentRejected ) ;
88+ } else if ( getDocumentRejected . length > 0 || getDocumentNull . length > 0 ) {
89+ // Partial failure - log to console but don't block UI
90+ if ( getDocumentRejected . length > 0 ) {
91+ logger . warn ( `Failed to load ${ getDocumentRejected . length } document(s) due to query rejection` ) ;
92+ logger . debug ( 'Rejected promises:' , getDocumentRejected ) ;
93+ }
94+ if ( getDocumentNull . length > 0 ) {
95+ logger . warn ( `${ getDocumentNull . length } document(s) not found (returned null):` , getDocumentNull ) ;
96+ logger . debug (
97+ 'These documents have list entries but no corresponding document records - possible orphaned list entries' ,
98+ ) ;
99+ }
79100 }
101+
102+ // Filter out null/undefined documents to prevent downstream errors
80103 const documentValues = getDocumentResolutions
81104 . filter ( ( r ) => r . status === 'fulfilled' )
82- . map ( ( r ) => r . value ?. data ?. getDocument ) ;
105+ . map ( ( r ) => r . value ?. data ?. getDocument )
106+ . filter ( ( doc ) => doc != null ) ;
83107
108+ logger . debug ( `Successfully loaded ${ documentValues . length } of ${ objectKeys . length } requested documents` ) ;
84109 return documentValues ;
85110 } ,
86111 [ setErrorMessage ] ,
@@ -256,11 +281,13 @@ const useGraphQlApi = ({ initialPeriodsToLoad = DOCUMENT_LIST_SHARDS_PER_DAY * 2
256281 const documentData = await documentDataPromise ;
257282 const objectKeys = documentData . map ( ( item ) => item . ObjectKey ) ;
258283 const documentDetails = await getDocumentDetailsFromIds ( objectKeys ) ;
259- // Merge document details with PK and SK
260- return documentDetails . map ( ( detail ) => {
261- const matchingData = documentData . find ( ( item ) => item . ObjectKey === detail . ObjectKey ) ;
262- return { ...detail , ListPK : matchingData . PK , ListSK : matchingData . SK } ;
263- } ) ;
284+ // Merge document details with PK and SK, filtering out nulls to prevent shard-level failures
285+ return documentDetails
286+ . filter ( ( detail ) => detail != null )
287+ . map ( ( detail ) => {
288+ const matchingData = documentData . find ( ( item ) => item . ObjectKey === detail . ObjectKey ) ;
289+ return { ...detail , ListPK : matchingData . PK , ListSK : matchingData . SK } ;
290+ } ) ;
264291 } ) ;
265292
266293 const documentValuesPromises = documentDetailsPromises . map ( async ( documentValuesPromise ) => {
0 commit comments