Skip to content

Commit aa8d4a6

Browse files
mandariniSumit Kumar
andcommitted
fix(storage)!: do not throw error when file does not exist in exists method (#1838)
Co-authored-by: Sumit Kumar <sumitkumar@kgpian.iitkgp.ac.in>
1 parent 9d865f8 commit aa8d4a6

3 files changed

Lines changed: 40 additions & 2 deletions

File tree

packages/core/storage-js/src/packages/StorageFileApi.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
967967
* @category Storage
968968
* @subcategory File Buckets
969969
* @param path The file path, including the file name. For example `folder/image.png`.
970-
* @returns Promise with response containing boolean indicating file existence or error
970+
* @returns `{ data: true, error: null }` when the file exists, `{ data: false, error: null }` when it does not (HTTP 400 or 404), or throws/returns a `StorageError` for any other failure.
971971
*
972972
* @example Check file existence
973973
* ```js
@@ -1009,7 +1009,7 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
10091009
: undefined
10101010

10111011
if (status !== undefined && [400, 404].includes(status)) {
1012-
return { data: false, error }
1012+
return { data: false, error: null }
10131013
}
10141014
}
10151015

packages/core/storage-js/test/storageFileApi.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ describe('Object API', () => {
614614

615615
const resNotExists = await storage.from(bucketName).exists('do-not-exists')
616616
expect(resNotExists.data).toEqual(false)
617+
expect(resNotExists.error).toBeNull()
617618

618619
// should throw when .throwOnError is enabled
619620
await expect(

packages/core/storage-js/test/storageFileApiErrorHandling.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,43 @@ describe('File API Error Handling', () => {
239239
})
240240
})
241241

242+
describe('exists', () => {
243+
it('returns { data: false, error: null } when the file does not exist (404)', async () => {
244+
global.fetch = jest.fn().mockResolvedValue(new Response(null, { status: 404 }))
245+
const storage = new StorageClient(URL, { apikey: KEY })
246+
247+
const { data, error } = await storage.from(BUCKET_ID).exists('missing.jpg')
248+
expect(data).toBe(false)
249+
expect(error).toBeNull()
250+
})
251+
252+
it('returns { data: false, error: null } when the server responds 400 (current Storage API behavior for missing objects)', async () => {
253+
global.fetch = jest
254+
.fn()
255+
.mockResolvedValue(
256+
new Response(JSON.stringify({ message: 'Bad Request' }), { status: 400 })
257+
)
258+
const storage = new StorageClient(URL, { apikey: KEY })
259+
260+
const { data, error } = await storage.from(BUCKET_ID).exists('whatever.jpg')
261+
expect(data).toBe(false)
262+
expect(error).toBeNull()
263+
})
264+
265+
it('surfaces an error for genuine failures (e.g., 500 server error)', async () => {
266+
global.fetch = jest
267+
.fn()
268+
.mockResolvedValue(
269+
new Response(JSON.stringify({ message: 'Internal Server Error' }), { status: 500 })
270+
)
271+
const storage = new StorageClient(URL, { apikey: KEY })
272+
273+
await expect(storage.from(BUCKET_ID).exists('whatever.jpg')).rejects.toBeInstanceOf(
274+
StorageError
275+
)
276+
})
277+
})
278+
242279
describe('createSignedUrl', () => {
243280
it('handles network errors', async () => {
244281
const mockError = new Error('Network failure')

0 commit comments

Comments
 (0)