fix(vendor): stop detail route crashing when vendor fetch fails

The vendor detail page and layout called api.vendors.getById without a
try/catch. The API client throws ApiError on any non-2xx, so a 404 (missing
vendor), 401, or 5xx during SSR threw out of the server component and
white-screened the whole route with a generic "server-side exception" —
the existing `if (!vendor)` fallback was never reached.

Guard both fetches: log the error and degrade gracefully (page shows
"Vendor not found", layout renders chrome with a fallback title).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
ERP-System 2026-06-08 16:23:29 +04:00
parent f9aac2db37
commit 29d90b5e71
2 changed files with 18 additions and 4 deletions

View File

@ -10,8 +10,15 @@ export default async function layout(props: {
}) { }) {
const { id } = await props.params const { id } = await props.params
const api = await getServerApi() const api = await getServerApi()
// Guard the fetch: a failed request (404/401/5xx) must not throw and crash
// the whole route — render the chrome with a fallback title instead.
let vendor: Record<string, any> | undefined
try {
const response = (await api.vendors.getById(id)) as { data?: Record<string, any> } const response = (await api.vendors.getById(id)) as { data?: Record<string, any> }
const vendor = response?.data vendor = response?.data
} catch (err) {
console.error(`Failed to load vendor ${id} (layout):`, err)
}
const company = vendor?.company_name as string | undefined const company = vendor?.company_name as string | undefined
const fullName = [vendor?.first_name, vendor?.last_name].filter(Boolean).join(" ").trim() const fullName = [vendor?.first_name, vendor?.last_name].filter(Boolean).join(" ").trim()

View File

@ -6,8 +6,15 @@ export default async function VendorDetailPage(props: { params: Promise<{ id: st
const api = await getServerApi() const api = await getServerApi()
// The OpenAPI schema doesn't yet describe GET /api/vendors/{id} (only PUT/DELETE), // The OpenAPI schema doesn't yet describe GET /api/vendors/{id} (only PUT/DELETE),
// so cast through `any` here until the schema is regenerated. // so cast through `any` here until the schema is regenerated.
// Guard the fetch: a failed request (404/401/5xx) must degrade gracefully
// instead of throwing and white-screening the whole route.
let vendor: Record<string, any> | undefined
try {
const response = (await api.vendors.getById(id)) as { data?: Record<string, any> } const response = (await api.vendors.getById(id)) as { data?: Record<string, any> }
const vendor = response?.data vendor = response?.data
} catch (err) {
console.error(`Failed to load vendor ${id}:`, err)
}
if (!vendor) { if (!vendor) {
return <div className="text-muted-foreground p-6">Vendor not found.</div> return <div className="text-muted-foreground p-6">Vendor not found.</div>