fix: Properly handle errors in Upload Api (related to StorageError)
What kind of change does this PR introduce?
Fix the error handling of upload, update and uploadToSignedUrl APIs so that they properly return StorageError instead of API's error schema.
What is the current behavior?
Multiple issues and PRs have been discussing this error for over a year. #214 #165
There are a bunch of helper functions at lib/fetch.ts that catch errors returned by the server and construct StorageError instance. Nearly all requests are using these helpers, except for uploadOrUpdate and uploadToSignedUrl in StorageFileApi, making their return types inconsistent:
Typescript declarations say the error returns are like:
{
data: null,
error: StorageError
}
However, without the helper functions, they actually return the error schema:
{
data: null,
error: { error: string, message: string, statusCode: string }
}
What is the new behavior?
This fix replaces raw fetch for uploadOrUpdate and uploadToSignedUrl with post and put helper functions so that their returns match the type declarations.
Additional context
It appears upload APIs are not using helpers because _getRequestParams will force body to be json type, which is an easy fix.
But if you think this part should not be touched, an alternative solution could be just patch the typings.
{
data: null,
error: StorageError | ErrorSchema
}
I think this is a good change, and it also resolves an issue that causes a fatal error if the upload response is not JSON (e.g. a cloudflare html error). The request helpers handle this case, but these two methods that don't use them do not.
@fenos can we merge this change? It is a breaking change to the actual return content of these two methods, BUT it makes them align correctly with the existing typedef. Currently actual return content is not aligned with the typedef return type
:tada: This PR is included in version 2.7.2 :tada:
The release is available on:
Your semantic-release bot :package::rocket:
Just a heads up that I believe this change broke our production app when Deno automatically picked up this new version during library resolution. I can also see the test are failing on main: https://github.com/supabase/storage-js/actions/runs/14620566129/job/41019236490 and that is similar to what we saw - when trying to upload image data as uint8array it gets recast as an object and what gets stored in the storage bucket is a json array with the image bytes as an array of numbers.
@mpierre Thanks for letting us know about this. I've introduced a PR ( #226 ) that should resolve this issue.