Context
PR #51 review (Round 3, thread #7) flagged that readJson() in brand-loader.ts catches isENOENT(err) to map missing files to BrandIncompleteError. The logo route (app/api/brands/[slug]/logos/[id]/route.ts) has the same pattern.
Currently only LocalFsAdapter is implemented, so isENOENT() (checking err.code === "ENOENT") works. When AzureBlobAdapter lands (Slice 4), Azure SDK throws RestError with statusCode === 404 / code === "BlobNotFound" — these won't match isENOENT(), causing missing-blob reads to surface as 500s instead of the expected 400/404.
Proposed fix
Normalize not-found errors inside each adapter so consumers never need to know the backend:
- Option A: Adapters catch provider-specific not-found and re-throw a shared
StorageNotFoundError.
- Option B: Add a
readFileOrNull() method that returns null instead of throwing.
Either way, isENOENT() callers (readJson, logo route, etc.) should be updated to use the normalized path.
Affected files
lib/cast/server/storage-adapter.ts (interface + LocalFsAdapter)
lib/cast/server/brand-loader.ts (readJson())
app/api/brands/[slug]/logos/[id]/route.ts (error catch)
Related
Context
PR #51 review (Round 3, thread #7) flagged that
readJson()inbrand-loader.tscatchesisENOENT(err)to map missing files toBrandIncompleteError. The logo route (app/api/brands/[slug]/logos/[id]/route.ts) has the same pattern.Currently only
LocalFsAdapteris implemented, soisENOENT()(checkingerr.code === "ENOENT") works. WhenAzureBlobAdapterlands (Slice 4), Azure SDK throwsRestErrorwithstatusCode === 404/code === "BlobNotFound"— these won't matchisENOENT(), causing missing-blob reads to surface as 500s instead of the expected 400/404.Proposed fix
Normalize not-found errors inside each adapter so consumers never need to know the backend:
StorageNotFoundError.readFileOrNull()method that returnsnullinstead of throwing.Either way,
isENOENT()callers (readJson, logo route, etc.) should be updated to use the normalized path.Affected files
lib/cast/server/storage-adapter.ts(interface +LocalFsAdapter)lib/cast/server/brand-loader.ts(readJson())app/api/brands/[slug]/logos/[id]/route.ts(error catch)Related
listPrefixesadapter method)