diff --git a/src/error.spec.ts b/src/error.spec.ts new file mode 100644 index 0000000..d69e5b2 --- /dev/null +++ b/src/error.spec.ts @@ -0,0 +1,17 @@ +import {UnexpectedObjectError} from './error'; + +describe('UnexpectedObjectError', () => { + it('works as expected', () => { + const item = {it: 'works'}; + try { + throw new UnexpectedObjectError(item as any); + } catch (e: any) { + expect(e.name).toEqual('UnexpectedObjectError'); + expect(e.toString()).toEqual('UnexpectedObjectError: DataTransferItem is not a file'); + expect(e).toBeInstanceOf(Error); + expect(e).toBeInstanceOf(UnexpectedObjectError); + expect(e.item).toEqual(item); + expect(e.stack).toBeDefined(); + } + }); +}); diff --git a/src/error.ts b/src/error.ts new file mode 100644 index 0000000..ba27fa0 --- /dev/null +++ b/src/error.ts @@ -0,0 +1,8 @@ +export class UnexpectedObjectError extends Error { + item: DataTransferItem; + constructor(item: DataTransferItem) { + super('DataTransferItem is not a file'); + this.item = item; + this.name = 'UnexpectedObjectError'; + } +} diff --git a/src/file-selector.spec.ts b/src/file-selector.spec.ts index 412420e..a8f9d83 100644 --- a/src/file-selector.spec.ts +++ b/src/file-selector.spec.ts @@ -337,7 +337,7 @@ it('should reject when getAsFileSystemHandle resolves to null', async () => { const evt = dragEvtFromItems([ dataTransferItemWithFsHandle(null, null) ]); - expect(fromEvent(evt)).rejects.toThrow('[object Object] is not a File'); + expect(fromEvent(evt)).rejects.toThrow('DataTransferItem is not a file'); }); it('should fallback to getAsFile when getAsFileSystemHandle resolves to undefined', async () => { diff --git a/src/file-selector.ts b/src/file-selector.ts index 33717d7..82cdd95 100644 --- a/src/file-selector.ts +++ b/src/file-selector.ts @@ -1,6 +1,6 @@ +import {UnexpectedObjectError} from './error'; import {FileWithPath, toFileWithPath} from './file'; - const FILES_TO_IGNORE = [ // Thumbnail cache files for macOS and Windows '.DS_Store', // macOs @@ -130,7 +130,7 @@ async function fromDataTransferItem(item: DataTransferItem, entry?: FileSystemEn if (globalThis.isSecureContext && typeof (item as any).getAsFileSystemHandle === 'function') { const h = await (item as any).getAsFileSystemHandle(); if (h === null) { - throw new Error(`${item} is not a File`); + throw new UnexpectedObjectError(item); } // It seems that the handle can be `undefined` (see https://github.com/react-dropzone/file-selector/issues/120), // so we check if it isn't; if it is, the code path continues to the next API (`getAsFile`). @@ -142,7 +142,7 @@ async function fromDataTransferItem(item: DataTransferItem, entry?: FileSystemEn } const file = item.getAsFile(); if (!file) { - throw new Error(`${item} is not a File`); + throw new UnexpectedObjectError(item); } const fwp = toFileWithPath(file, entry?.fullPath ?? undefined); return fwp;