Project: doctolib-doctolib · Branch: .invalid · Mode: ` · **Model:**claude-haiku-4-5-20251001`
Stats: 1 user messages, 23 tool calls, tools used: Bash, Read.
Conversation
Turn 1 — User
I'm re-designing error propagation in the NHR document list flow. Instead of throwing exceptions, I want errors to be returned as data through the call chain. I need to understand every type that would need to change.
Call chain to trace:
DmpNhrAdapter.searchDocuments() [packages/@doctolib/national-health-records]
└─ returns NhrDocumentSearchResult
└─ useSearchDocuments.ts [packages/@doctolib/national-health-records]
└─ queryClient.fetchQuery → some result
└─ SearchDocumentsFn [injected into NhrDocumentListModal]
Please investigate:
-
useSearchDocuments.ts— full file Path:packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.tsShow the complete file. I specifically need to know: - What doesqueryClient.fetchQueryreturn? - How isNhrDocumentSearchResulttransformed before being returned? - What is the return type of the hook itself? -
NhrDocumentSearchResulttype definition Search in bothpackages/@doctolib/national-health-records/andtreatment-plan/for the definition ofNhrDocumentSearchResult. Show the full interface. -
SearchDocumentsFntype Path:treatment-plan/packages/tpf-national-health-records-ui/src/types.tsShow the full file. What doesSearchDocumentsFnreturn? -
NhrDocumentListModalfetch result usage Path:treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListModal.tsxLines 42–51: show how the result ofsearchDocuments(appliedFilters)is destructured. -
useNhrDocumentListVariantoruseDmpDocumentListVariant— how does the monolith wire upsearchDocumentsas a prop to the modal? Search for these hooks in the monolith and show what they return/inject.
Report exact file paths and line numbers for everything found.
Turn 1 — Assistant
I'll trace through this error propagation chain systematically. Let me start by exploring the key files and types.
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib -type f -name "useSearchDocuments.ts" 2>/dev/null
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts /Users/USER/workspace/doctolib/doctolib/.claude/worktrees/fhir-2144_nhr-document-list-add-action-config-column/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts
Now let me read the key files:
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts
Tool results:
→ result (ok): 1 import { useQueryClient } from '@tanstack/react-query-v5' 2 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient' 3 import { isFeatureEnabled } from '@doctolib/variation_management' 4 import type { NhrDocumentListVariant, MapFiltersToSearchDocumentsParams, ServerFilters } from '../variants/types' 5 import { useNationalHealthRecords } from './useNationalHealthRecords' 6 import { generateNhrDocuments } from '../mocks/generateNhrDocuments' 7 import { filterMockedDocuments } …(truncated, 2782 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib -type f \( -name "*.ts" -o -name "*.tsx" \) -path "*/national-health-records/*" | xargs grep -l "NhrDocumentSearchResult" 2>/dev/null | head -20
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib -type f \( -name "*.ts" -o -name "*.tsx" \) -path "*/treatment-plan/*" | xargs grep -l "NhrDocumentSearchResult" 2>/dev/null | head -20
Tool results:
→ result (ok): (Bash completed with no output)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useNationalHealthRecords.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.test.ts /Users/USER/workspace/doctolib/doctolib/.claude/worktrees/crazy-volhard/packages/@doctolib/national-health-records/src/hooks/useNa …(truncated, 918 more chars)
Now let me search for the NhrDocumentSearchResult type definition and the SearchDocumentsFn:
Tools used:
Bash:grep -r "NhrDocumentSearchResult" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records --include="*.ts" --include="*.tsx" -n | head -30
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.test.ts:129: it('should return correctly transformed NhrDocumentSearchResult', async () => { /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.ts:17: NhrDocumentSearchResult, /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.ts:108:functio …(truncated, 735 more chars)
Good! Now let me look at the actual definition in the treatment-plan package:
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/treatment-plan -type f \( -name "*.ts" -o -name "*.tsx" \) | xargs grep -l "NhrDocumentSearchResult" 2>/dev/null | head -20
Tool results:
→ result (ok): bfs: error: /Users/USER/workspace/doctolib/doctolib/treatment-plan: No such file or directory.
Let me search for the treatment-plan directory:
Tools used:
Bash:find /Users/USER/workspace/doctolib -type d -name "treatment-plan" 2>/dev/null
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/treatment-plan /Users/USER/workspace/doctolib/worktrees/treatment-plan /Users/USER/workspace/doctolib/treatment-plan/backend/applications/treatment-plan /Users/USER/workspace/doctolib/worktrees/treatment-plan/fhir-2083/backend/applications/treatment-plan /Users/USER/workspace/doctolib/worktrees/treatment-plan/fhir-2079/backend/applications/treatment-plan /Users/USER/workspace/doctolib/worktrees/treatment-plan/fhir-2168_add-result-count-to-nhr-header/backend/applica …(truncated, 3649 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/treatment-plan -type f \( -name "*.ts" -o -name "*.tsx" \) | xargs grep -l "NhrDocumentSearchResult" 2>/dev/null | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/index.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/dist/index.d.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/types/api.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/types/index.ts /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/sr …(truncated, 2106 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/types/api.ts
Tool results:
→ result (ok): 1 import type { DateRange, NhrDocument, NhrDocumentFile } from '#business/types/document'
2 import type { NhrPatientInformation } from '#business/types/participant'
3
4 export type NhrResultStatus = 'success' | 'skipped' | 'error' | 'partial success'
5
6 type NhrResult = {
7 status: NhrResultStatus
8 message?: string
9 }
10
11 // Document Search
12 export type NhrDocumentSearchParams = {
13 formats?: string[]
14 categories?: string[]
15 status?: string
16 serviceStartDate?: DateRa
…(truncated, 2260 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/types/service.ts
Tool results:
→ result (ok): 1 import type {
2 NhrDocumentContentResult,
3 NhrDocumentMetadataUpdateProps,
4 NhrDocumentMetadataUpdateResult,
5 NhrDocumentSearchProps,
6 NhrDocumentSearchResult,
7 NhrGetDocumentsContentProps,
8 } from '#business/types/api'
9
10 export type CountryCode = 'fr' | 'mock'
11
12 export type NhrService = {
13 searchDocuments(props: NhrDocumentSearchProps): Promise<NhrDocumentSearchResult>
14 getDocumentsContent(props: NhrGetDocumentsContentProps): Promise<NhrDocumentContentResult
…(truncated, 792 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/treatment-plan -path "*/tpf-national-health-records-ui/src/types.ts" -type f
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/types.ts /Users/USER/workspace/doctolib/treatment-plan/.claude/worktrees/stupefied-lewin/packages/tpf-national-health-records-ui/src/types.ts /Users/USER/workspace/doctolib/treatment-plan/.claude/worktrees/friendly-lalande/packages/tpf-national-health-records-ui/src/types.ts
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/types.ts
Tool results:
→ result (ok): 1 import type { DesignSystemIconComponent } from '@doctolib/design-system-icons'
2 import type { NhrDocument } from '@doctolib/tpf-national-health-records'
3 import type { ReactNode } from 'react'
4
5 export type NhrPatientInfo = {
6 fullName: string
7 gender: 'male' | 'female' | 'other'
8 birthDate: string
9 age: number
10 }
11
12 export type ColumnConfig = {
13 key: string
14 header: string
15 sortable: boolean
16 /** Only required when sortable: true. Returns a string for lo
…(truncated, 2614 more chars)
Tools used:
Bash:find /Users/USER/workspace/doctolib/treatment-plan -path "*/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListModal.tsx" -type f
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListModal.tsx /Users/USER/workspace/doctolib/treatment-plan/.claude/worktrees/stupefied-lewin/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListModal.tsx /Users/USER/workspace/doctolib/treatment-plan/.claude/worktrees/friendly-lalande/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentList …(truncated, 9 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListModal.tsx(1–100)
Tool results:
→ result (ok): 1 import { Modal } from '@doctolib/design-system/Modal'
2 import { ModalBody } from '@doctolib/design-system/ModalBody'
3 import type { NhrDocument } from '@doctolib/tpf-national-health-records'
4 import { useEffect, useMemo, useState } from 'react'
5
6 import type { ActionConfig, ColumnConfig, FilterConfig, NhrPatientInfo, SearchDocumentsFn } from '../../types'
7 import { NhrDocumentList } from '../NhrDocumentList/NhrDocumentList'
8
9 export type NhrDocumentListModalProps = {
10 isOpen: boo
…(truncated, 2583 more chars)
Perfect! Now let me search for how this is wired up in the monolith:
Tools used:
Bash:grep -r "useNhrDocumentListVariant\|useDmpDocumentListVariant" /Users/USER/workspace/doctolib/doctolib --include="*.ts" --include="*.tsx" -l | head -20
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/index.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/index.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/useDmpDocumentListVariant.ts /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/useNhrDocumentListVariant.ts /Users/USER/workspace/doctolib/doctolib/p …(truncated, 265 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/useNhrDocumentListVariant.ts
Tool results:
→ result (ok): 1 import { useProductLineVariation, ProductLineKey } from '@doctolib/variation_management'
2 import type { DocumentSearchOptions, NhrDocumentListVariant } from './types'
3 import { useDmpDocumentListVariant } from './dmp'
4
5 export const useNhrDocumentListVariant = (patient: DocumentSearchOptions['patient']): NhrDocumentListVariant | null => {
6 const dmpVariant = useDmpDocumentListVariant(patient)
7
8 return useProductLineVariation<NhrDocumentListVariant>({
9 variants: {
10 [Pr
…(truncated, 729 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/useDmpDocumentListVariant.ts
Tools used:
Bash:find /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants -name "types.ts" -o -name "types.tsx"
Tool results:
→ result (ok): 1 import { columnsFactory } from './factories/columnsFactory'
2 import { filtersFactory } from './factories/filtersFactory'
3 import type { NhrDocumentListVariant, DocumentSearchOptions } from '../types'
4 import useDmpSearchDocuments from '../../hooks/useSearchDocuments'
5 import { mapFiltersToSearchDocumentsParams } from './mappers/mapFiltersToSearchDocumentsParams'
6
7 export const useDmpDocumentListVariant = (patient: DocumentSearchOptions['patient']): NhrDocumentListVariant => {
8 const
…(truncated, 547 more chars)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/types.ts
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/types.ts
Tool results:
→ result (ok): 1 import type { ColumnConfig, FilterConfig } from '@doctolib/tpf-national-health-records-ui'
2 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient'
3 import type { NhrDocument, NhrDocumentSearchParams } from '@doctolib/tpf-national-health-records'
4
5 interface SearchDocumentsResult {
6 data: NhrDocument[]
7 total: number
8 }
9
10 export type NhrDocumentListVariant = {
11 columns: ColumnConfig[]
12 filters: FilterConfig[]
13 searchDocuments: (appliedFilters?: R
…(truncated, 1138 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.ts
Tool results:
→ result (ok): 1 import type { 2 DmpApi, 3 DmpAuthor, 4 DmpDocument, 5 DmpDocumentContent, 6 SearchProps, 7 SearchResult as DmpSearchResult, 8 } from '@doctolib/dmp' 9 import { DOCUMENT_STATUS, DOCUMENT_VISIBILITY, getPatientInsForDMP } from '@doctolib/dmp' 10 import { isUnstructured } from '@doctolib/cda/types/UnstructuredBody' 11 import { isStructured } from '@doctolib/cda/types/StructuredBody' 12 import type { Patient } from 'monolith_DEPRECATED/types/doctor/api/Patient' 13 import type { 14 Nh …(truncated, 6244 more chars)
Perfect! Now let me verify the complete call chain by checking how this is used:
Tools used:
Bash:grep -r "useNhrDocumentListVariant\|useDmpDocumentListVariant" /Users/USER/workspace/doctolib/doctolib --include="*.tsx" -A 5 | grep -E "(useNhrDocumentListVariant|useDmpDocumentListVariant|searc …(truncated, 23 more chars)
Tool results:
→ result (ok): /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.tsx:import { actionsBuilder, useNhrDocumentListVariant } from '@doctolib/national-health-records' /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.tsx: const nhrVariant = useNhrDocumentListVariant(patient) /Users/USER/workspace/doctolib/doctolib/packages …(truncated, 826 more chars)
Tools used:
Read:/Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.tsx(1–150)
Tool results:
→ result (ok): 1 import PatientFileIcon from 'images/icons/patient-file-icon.svg?as-react-component' 2 import PatientAppointmentIcon from 'images/icons/patient-appointment-icon.svg?as-react-component' 3 import { type ComponentType, lazy, useContext, useMemo, Suspense } from 'react' 4 import classNames from 'classnames' 5 import AccountContext from 'monolith_DEPRECATED/contexts/doctor/AccountContext' 6 import INSiAutomaticCallContext from '@doctolib/financial_os_api/public/contexts/INSiAutomaticCallContext' 7 i …(truncated, 7698 more chars)
Perfect! Now let me verify the return type of useSearchDocuments more carefully:
Tools used:
Bash:grep -A 15 "return async (appliedFilters" /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts
Tool results:
→ result (ok): return async (appliedFilters: Record<string, unknown> = {}) => { if (isFeatureEnabled('nhr_document_list_search_mocked')) { const allMockedDocuments = generateNhrDocuments({ count: 101 }) const filteredDocuments = filterMockedDocuments(allMockedDocuments, appliedFilters as ServerFilters) return { data: filteredDocuments, total: filteredDocuments.length } }
const { ins } = patient
if (!ins) return { data: [], total: 0 }
const documents = await queryClient.f
…(truncated, 298 more chars)
Excellent! Now I have the complete picture. Let me create a comprehensive report of the error propagation chain and all types that would need to change.
Comprehensive Error Propagation Type Analysis
I've traced the complete call chain. Here's every type that would need to change to shift from exceptions to error-as-data:
1. ROOT: DmpNhrAdapter.searchDocuments()
File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/business/adapters/DmpNhrAdapter.ts
Lines: 145-153
Current signature:
async searchDocuments(props: NhrDocumentSearchProps): Promise<NhrDocumentSearchResult>
Returns:
{ documents: NhrDocument[] }
Throws: DMPAccessDeniedByExcededThreshold (caught at line 54 in useSearchDocuments.ts)
2. Upstream: NhrDocumentSearchResult type definition
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records/src/business/types/api.ts
Lines: 28-30
Current definition:
export type NhrDocumentSearchResult = {
documents: NhrDocument[]
}
This needs to be extended to carry error information.
3. Hook: useSearchDocuments.ts
File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/hooks/useSearchDocuments.ts
Lines: 18-62 (complete file)
Returns via the closure (line 21):
NhrDocumentListVariant['searchDocuments']
Which evaluates to (from variants/types.ts line 13):
(appliedFilters?: Record<string, unknown>) => Promise<SearchDocumentsResult>
Key transformations:
- Line 43-57: queryClient.fetchQuery() returns NhrDocument[] (from line 50: result?.documents ?? [])
- Line 37 & 58: Wraps in { data: ..., total: ... }
The hook returns a wrapped result but currently discards error information from nhrOperations.searchDocuments().
4. Local Result Type: SearchDocumentsResult
File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/types.ts
Lines: 5-8
Current definition:
interface SearchDocumentsResult {
data: NhrDocument[]
total: number
}
This is the exact return type of the function consumed by the modal (line 13 defines searchDocuments in NhrDocumentListVariant).
5. UI Contract: SearchDocumentsFn type
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/types.ts
Lines: 58-60
Current definition:
export type SearchDocumentsFn = (
appliedFilters?: Record<string, unknown>
) => Promise<{ data: NhrDocument[]; total?: number }>
6. Modal Usage: NhrDocumentListModal.tsx
File: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentListModal/NhrDocumentListModal.tsx
Lines: 42-51 (destructuring)
Current destructuring:
const { data, total: fetchedTotal } = await searchDocuments(appliedFilters)
setDocumentsState({ rows: data, total: fetchedTotal, isLoading: false })
Line 30-38 (state shape):
[{ rows, total, isLoading }, setDocumentsState] = useState<{
rows: NhrDocument[]
total: number | undefined
isLoading: boolean
}>
7. Variant Factory: NhrDocumentListVariant type
File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/types.ts
Lines: 10-14
Current definition:
export type NhrDocumentListVariant = {
columns: ColumnConfig[]
filters: FilterConfig[]
searchDocuments: (appliedFilters?: Record<string, unknown>) => Promise<SearchDocumentsResult>
}
8. Hook Factories: useDmpDocumentListVariant & useNhrDocumentListVariant
useDmpDocumentListVariant:
- File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/dmp/useDmpDocumentListVariant.ts
- Lines: 7-14
- Calls useDmpSearchDocuments() and returns it as searchDocuments property in NhrDocumentListVariant
useNhrDocumentListVariant:
- File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/national-health-records/src/variants/useNhrDocumentListVariant.ts
- Lines: 5-20
- Returns variant from useDmpDocumentListVariant() wrapped in product line variation selection
9. Monolith Integration: PatientCard.tsx
File: /Users/USER/workspace/doctolib/doctolib/packages/@doctolib/shared_patient_file_and_appointment_page_components/src/desktop/PatientCard/PatientCard.tsx
Lines: 60, 131
Usage:
const nhrVariant = useNhrDocumentListVariant(patient)
searchDocuments={nhrVariant?.searchDocuments ?? (() => Promise.resolve({ data: [] }))}
Summary: Types Requiring Changes
| Type / Interface | Location | Lines | Current Shape | What Must Change |
|---|---|---|---|---|
NhrDocumentSearchResult |
treatment-plan/tpf-national-health-records/business/types/api.ts | 28-30 | { documents: NhrDocument[] } |
Add error/status field |
SearchDocumentsResult |
doctolib/variants/types.ts | 5-8 | { data: NhrDocument[], total: number } |
Add error/status field |
SearchDocumentsFn |
treatment-plan/tpf-national-health-records-ui/types.ts | 58-60 | Promise<{ data: NhrDocument[], total?: number }> |
Return type must include error state |
useSearchDocuments hook return |
doctolib/hooks/useSearchDocuments.ts | 21, 33-59 | Returns SearchDocumentsResult wrapped in Promise |
Must transform error from nhrOperations.searchDocuments() into result shape |
NhrDocumentListVariant.searchDocuments |
doctolib/variants/types.ts | 13 | Function type | Signature changes to propagate errors |
NhrDocumentListModal state shape |
treatment-plan/tpf-national-health-records-ui/NhrDocumentListModal.tsx | 30-38 | { rows, total, isLoading } |
Add error/status field to accommodate errors from searchDocuments |
NhrDocumentListModal destructuring |
treatment-plan/tpf-national-health-records-ui/NhrDocumentListModal.tsx | 46 | Destructures only { data, total } |
Must handle error case in result |
Call Chain With Type Transformations
DmpNhrAdapter.searchDocuments()
↓ Returns: NhrDocumentSearchResult { documents: [] } OR throws
useSearchDocuments() hook (line 33)
↓ Wraps via queryClient.fetchQuery + maps to { data, total }
↓ Returns: SearchDocumentsResult { data: NhrDocument[], total: number }
useDmpDocumentListVariant()
↓ Passes searchDocuments as prop
↓ Returns: NhrDocumentListVariant { searchDocuments, columns, filters }
useNhrDocumentListVariant()
↓ Wraps in product line variation
↓ Returns: NhrDocumentListVariant | null
PatientCard.tsx (line 60)
↓ Receives nhrVariant with searchDocuments function
↓ Passes to NhrEntryPointModule (line 131)
NhrDocumentListModal.tsx (line 46)
↓ Calls: const { data, total } = await searchDocuments(appliedFilters)
↓ Sets state with data/total (line 47)
The critical redesign point is that currently useSearchDocuments swallows the error from nhrOperations.searchDocuments() via the retry logic (line 53-56) and only lets it propagate if retry limit is exceeded. To return errors as data, you must:
- Extend all
*SearchResulttypes to include error/status fields - Catch in
useSearchDocuments(line 46-49) and map exceptions to the result type - Update
NhrDocumentListModalto read and display error state from the result