fix(storage): expose service error code on StorageApiError - #2537
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughSummary by CodeRabbit
Walkthrough
Assessment against linked issues
Possibly related PRs
Suggested labels: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
mandarini
left a comment
There was a problem hiding this comment.
Hi @thribhuvan003, thank you so much for contributing to Supabase! 💚
This is exactly the right fix. You landed on the correct field: the Storage service always sends the documented code (NoSuchKey, AccessDenied, and so on) as code in the response body, and the SDK was quietly dropping it because statusCode took precedence. Passing err.code through onto a dedicated code property, and including it in toJSON(), is precisely what we want.
Two small things before we merge, neither blocking:
-
In the new fetch test the mock body is
{ code: 'NoSuchKey', message: 'Object not found' }with nostatusCode. That happens to exercise the legacy fallback wherestatusCodealso becomes'NoSuchKey', which is not what a real server sends. The real payload always includes both, like{ statusCode: '404', code: 'NoSuchKey', message: '...' }. Could you tweak the fixture to includestatusCodeso it mirrors reality? The assertion oncodestays the same. -
Optional, but nice to have: a small integration test that downloads a missing object and asserts
error.code, so we lock in that the server really does send what we are reading. Happy to merge without it if you would rather keep the PR tight.
Thank you again for the clean, focused patch and for the tests that actually fail without the change. Contributions like this are what keep the SDK healthy.
@supabase/auth-js
@supabase/functions-js
@supabase/postgrest-js
@supabase/realtime-js
@supabase/storage-js
@supabase/supabase-js
commit: |
|
thanks @mandarini, that means a lot 💚 done on (1) — the fetch fixture now sends on (2): i'd like to add it, but i can't run the storage docker stack in my dev env to verify the exact |
|
Really appreciate the follow-up, and you asked exactly the right question in (2): what Here's why: the server generates Your instinct not to push an integration assertion you hadn't seen pass was correct, it would have failed, and that's what surfaced this. The client patch is the right shape, but it can't deliver until the server includes |
|
@thribhuvan003 good news btw, storage team added it on their timeline! so once they make a PR i will link it here, and once PR is merged and released, we can move on with your PR! |
|
amazing, thank you 🙌 no rush at all on my end — i'll watch for the storage team's PR and align mine once it lands. |
|
@thribhuvan003 this is now shipped on the storage server! |
1c9c7c0 to
834f93f
Compare
|
Thanks @mandarini — great news, and thank you for driving the server-side change! I've rebased onto the latest master, and the client already reads the newly shipped One thing on the SDK Compliance check: it flags |
Registers a new area-level feature for exposing the machine-readable service error code (e.g. NoSuchKey, AccessDenied) on thrown storage errors, covering both file and vector bucket operations. Needed to map StorageApiError.code / StorageVectorsApiError.code being added in supabase/supabase-js#2537.
Registers a new area-level feature for exposing the machine-readable service error code (e.g. NoSuchKey, AccessDenied) on thrown storage errors, covering both file and vector bucket operations. Needed to map StorageApiError.code / StorageVectorsApiError.code being added in supabase/supabase-js#2537.
834f93f to
691cf89
Compare
This PR updates `@supabase/supabase-js` to v2.112.3. **Source**: manual --- ## Release Notes ## v2.112.3 ## 2.112.3 (2026-08-11) ### 🩹 Fixes - **supabase:** add trace context headers to canonical CORS allow-list ([#2603](supabase/supabase-js#2603)) - **supabase:** improve trace propagation sampling and diagnostics ([#2604](supabase/supabase-js#2604)) ### ❤️ Thank You - Katerina Skroumpelou @mandarini ## v2.112.2 ## 2.112.2 (2026-08-06) ### 🩹 Fixes - **realtime:** prevent duplicate on bindings ([#2594](supabase/supabase-js#2594)) - **realtime:** clear stale join payload on sign-out ([#2597](supabase/supabase-js#2597)) ### ❤️ Thank You - Filipe Cabaço @filipecabaco - Vaibhav @7ttp ## v2.112.1 ## 2.112.1 (2026-08-05) ### 🩹 Fixes - **auth:** preserve 5xx error message ([#2587](supabase/supabase-js#2587)) - **realtime:** ensure setAuth doesn't disable token refresh ([#2592](supabase/supabase-js#2592)) ### ❤️ Thank You - Eduardo Gurgel - Vaibhav @7ttp ## v2.112.0 ## 2.112.0 (2026-08-03) ### 🚀 Features - **supabase:** move OpenTelemetry tracing to opt-in /tracing subpath ([#2583](supabase/supabase-js#2583)) ### 🩹 Fixes - **auth:** accept uppercase UUIDs in validateUUID ([#2467](supabase/supabase-js#2467)) - **postgrest:** honour throwOnError when maybeSingle finds multiple rows ([#2580](supabase/supabase-js#2580)) - **storage:** resolve createSignedUrls return type mismatch ([#2474](supabase/supabase-js#2474)) - **storage:** expose service error code on StorageApiError ([#2537](supabase/supabase-js#2537)) - **supabase:** forward db retry option ([#2571](supabase/supabase-js#2571)) ### ❤️ Thank You - Anubhav Anand @i-anubhav-anand - Gourab Singha @gourabsingha1 - Juhef @juheff - Katerina Skroumpelou @mandarini - Thribhuvan - Vaibhav @7ttp - Zuhef Ahmed @Zuhef This PR was created automatically. Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
This PR updates @supabase/*-js libraries to version 2.112.3. **Source**: manual **Changes**: - Updated @supabase/supabase-js to 2.112.3 - Updated @supabase/auth-js to 2.112.3 - Updated @supabase/realtime-js to 2.112.3 - Updated @supabase/postgest-js to 2.112.3 - Refreshed pnpm-lock.yaml --- ## Release Notes ## v2.112.3 ## 2.112.3 (2026-08-11) ### 🩹 Fixes - **supabase:** add trace context headers to canonical CORS allow-list ([#2603](supabase/supabase-js#2603)) - **supabase:** improve trace propagation sampling and diagnostics ([#2604](supabase/supabase-js#2604)) ### ❤️ Thank You - Katerina Skroumpelou @mandarini ## v2.112.2 ## 2.112.2 (2026-08-06) ### 🩹 Fixes - **realtime:** prevent duplicate on bindings ([#2594](supabase/supabase-js#2594)) - **realtime:** clear stale join payload on sign-out ([#2597](supabase/supabase-js#2597)) ### ❤️ Thank You - Filipe Cabaço @filipecabaco - Vaibhav @7ttp ## v2.112.1 ## 2.112.1 (2026-08-05) ### 🩹 Fixes - **auth:** preserve 5xx error message ([#2587](supabase/supabase-js#2587)) - **realtime:** ensure setAuth doesn't disable token refresh ([#2592](supabase/supabase-js#2592)) ### ❤️ Thank You - Eduardo Gurgel - Vaibhav @7ttp ## v2.112.0 ## 2.112.0 (2026-08-03) ### 🚀 Features - **supabase:** move OpenTelemetry tracing to opt-in /tracing subpath ([#2583](supabase/supabase-js#2583)) ### 🩹 Fixes - **auth:** accept uppercase UUIDs in validateUUID ([#2467](supabase/supabase-js#2467)) - **postgrest:** honour throwOnError when maybeSingle finds multiple rows ([#2580](supabase/supabase-js#2580)) - **storage:** resolve createSignedUrls return type mismatch ([#2474](supabase/supabase-js#2474)) - **storage:** expose service error code on StorageApiError ([#2537](supabase/supabase-js#2537)) - **supabase:** forward db retry option ([#2571](supabase/supabase-js#2571)) ### ❤️ Thank You - Anubhav Anand @i-anubhav-anand - Gourab Singha @gourabsingha1 - Juhef @juheff - Katerina Skroumpelou @mandarini - Thribhuvan - Vaibhav @7ttp - Zuhef Ahmed @Zuhef ## v2.111.0 ## 2.111.0 (2026-07-28) ### 🚀 Features - **auth:** store PKCE verifiers in per-flow slots to survive overlapping flows ([#2569](supabase/supabase-js#2569)) ### ❤️ Thank You - Katerina Skroumpelou @mandarini This PR was created automatically. Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
🔍 Description
What changed?
StorageApiErrornow carries the service error code (NoSuchKey,AccessDenied,ResourceAlreadyExists, etc.) on a dedicatedcodeproperty, and includes it intoJSON().The response body already contains this in
err.code—handleErrorinstorage-js/src/lib/common/fetch.tswas only using it as a fallback forstatusCodeand otherwise dropping it, so it never reached the error object. Now it is passed through to the new field.statusCodeis unchanged.Why was this change needed?
The Storage error-codes docs tell you to branch on codes like
AccessDenied/NoSuchKey, but the thrownStorageApiErrornever exposed them — it only hadstatusandstatusCode— so that pattern was impossible to implement without parsing the message string. This closes that gap.Closes #2536
📸 Screenshots/Examples
🔄 Breaking changes
Additive only — a new optional constructor arg and a new field.
codeisundefinedwhen the response has no code, and existingstatus/statusCodebehaviour is untouched.📋 Checklist
<type>(<scope>): <description>pnpm nx formatto ensure consistent code formatting📝 Additional notes
Added unit tests in both
errors.test.ts(thecodefield +toJSON) andfetch.test.ts(that acodein the response body reaches the error) — they fail without the change and pass with it.