supabase-js icon indicating copy to clipboard operation
supabase-js copied to clipboard

fix(storage)!: correct exists() error handling for non-existent files

Open mandarini opened this issue 4 months ago • 5 comments

authored by @SumitKumar-17 Transfered from: https://github.com/supabase/storage-js/pull/256

Bug Fix Report

I have successfully identified and fixed the bug reported in the issue. Here's what I found and resolved:

The Issue

The bug report was partially correct. The exists method was indeed present in both browser and Node.js builds (I confirmed it existed in the compiled output), but there was an error handling bug that made it appear to not work properly in certain cases.

The Root Cause

The problem was in the error handling logic of the exists method in src/packages/StorageFileApi.ts. When a file doesn't exist (resulting in a 404 HTTP status), the method would return { data: false, error: StorageError } instead of { data: false, error: null }.
This was incorrect behavior because:

  1. The operation (checking for existence) was successful
  2. Getting a 404 simply means the file doesn't exist, not that the operation failed
  3. The user should receive { data: false, error: null } to indicate "file doesn't exist, but the check was successful"

The Fix

I updated the exists method to properly handle both StorageApiError (which contains the status code directly) and StorageUnknownError (which contains the original error object), and return { data: false, error: null } when the error status is 400 or 404.

Changes Made

  1. Fixed error handling in the exists method to properly return { data: false, error: null } when a file doesn't exist
  2. Added proper TypeScript imports for StorageApiError
  3. Updated README documentation with an example of how to use the exists method

Verification

  • The project builds successfully with the fix
  • The method is available in all builds (main, module, UMD)
  • The fix aligns with the existing test expectations
  • Proper TypeScript types are maintained

Solves: https://github.com/supabase/supabase-js/issues/1600

Breaking change

This is a breaking change, and it can be added in the v3 planning.

mandarini avatar Oct 08 '25 12:10 mandarini

Coverage Status

coverage: 95.455% (+13.0%) from 82.5% when pulling 195ca1bff986f028ab811adbe0f61d6a580f5e7f on fix/storage-exists-frontend into 2d0bd770f984d6c2fc3889e6b5a7cc76d5d1f362 on master.

coveralls avatar Oct 08 '25 12:10 coveralls

@mandarini Ya let me look into it.

SumitKumar-17 avatar Oct 24 '25 13:10 SumitKumar-17

@itslenny I think this can work

if (status && [400, 404].indexOf(status) !== -1) {
          return { data: false, error }
        }

Users checking if (error) will correctly trigger the "not exists" logic when files don't exist

The Return Type Supports It The TypeScript return type already allows for both scenarios: So returning the actual error object is perfectly valid and expected.

Promise<
  | { data: boolean; error: null }
  | { data: boolean; error: StorageError }
>

The change ensures that users can properly handle both "file exists" and "file doesn't exist" scenarios using the error field, which is the standard pattern in Supabase APIs.

SumitKumar-17 avatar Oct 24 '25 19:10 SumitKumar-17

I will be parking this PR for now, since it will be a breaking change. We will consider this change for our v3 release. Thank you @SumitKumar-17

mandarini avatar Nov 06 '25 14:11 mandarini

Okay @mandarini

SumitKumar-17 avatar Nov 06 '25 15:11 SumitKumar-17