Repository: ROpdebee/mb-userscripts (ts)

Issue:
Improve error message on unsupported file formats
If we could, we should add the received MIME type in the error message (perhaps extract it from the fetch response header). We should also raise a specific error if we get text or HTML instead of images, since the user may have accidentally pasted the wrong link.

Pull request description:
fix(caa upload): improve error message on invalid file types
* Include actual MIME type returned by server in error message.
* Provide specific error message when content type is textual, as this may mean that the user is trying to use an unsupported provider.

Closes #238 

Patch:
diff --git a/src/mb_enhanced_cover_art_uploads/fetch.ts b/src/mb_enhanced_cover_art_uploads/fetch.ts
index b30e85e2..45f7c98d 100644
--- a/src/mb_enhanced_cover_art_uploads/fetch.ts
+++ b/src/mb_enhanced_cover_art_uploads/fetch.ts
@@ -207,7 +207,12 @@ export class ImageFetcher {
                 } else if (uint32view[0] === 0x46445025) {
                     resolve('application/pdf');
                 } else {
-                    reject(new Error(`${fileName} has an unsupported file type`));
+                    const actualMimeType = resp.responseHeaders.match(/content-type:\s*([^;\s]+)/i)?.[1];
+                    if (actualMimeType?.startsWith('text/')) {
+                        reject(new Error('Expected to receive an image, but received text. Perhaps this provider is not supported yet?'));
+                    } else {
+                        reject(new Error(`Expected "${fileName}" to be an image, but received ${actualMimeType ?? 'unknown file type'}.`));
+                    }
                 }
             });
             reader.readAsArrayBuffer(rawFile.slice(0, 4));


Test patch:
diff --git a/tests/mb_enhanced_cover_art_uploads/fetch.test.ts b/tests/mb_enhanced_cover_art_uploads/fetch.test.ts
index 6c591042..1ba10dc5 100644
--- a/tests/mb_enhanced_cover_art_uploads/fetch.test.ts
+++ b/tests/mb_enhanced_cover_art_uploads/fetch.test.ts
@@ -75,14 +75,36 @@ describe('fetching image contents', () => {
             .rejects.toBeInstanceOf(NetworkError);
     });
 
-    it('rejects on invalid file', async () => {
+    it('rejects on text response', async () => {
         mockXhr.mockResolvedValueOnce(createXhrResponse({
             finalUrl: 'https://example.com/broken',
             response: new Blob(['test']),
+            responseHeaders: 'Content-Type: text/html; charset=utf-8',
         }));
 
         await expect(fetcher.fetchImageContents(new URL('https://example.com/broken'), 'test.jpg', {}))
-            .rejects.toThrow('test.jpg has an unsupported file type');
+            .rejects.toThrow('Expected to receive an image, but received text. Perhaps this provider is not supported yet?');
+    });
+
+    it('rejects on invalid image', async () => {
+        mockXhr.mockResolvedValueOnce(createXhrResponse({
+            finalUrl: 'https://example.com/broken',
+            response: new Blob(['test']),
+            responseHeaders: 'Content-Type: application/json',
+        }));
+
+        await expect(fetcher.fetchImageContents(new URL('https://example.com/broken'), 'test.jpg', {}))
+            .rejects.toThrow('Expected "test.jpg" to be an image, but received application/json.');
+    });
+
+    it('rejects on invalid image without content-type header', async () => {
+        mockXhr.mockResolvedValueOnce(createXhrResponse({
+            finalUrl: 'https://example.com/broken',
+            response: new Blob(['test']),
+        }));
+
+        await expect(fetcher.fetchImageContents(new URL('https://example.com/broken'), 'test.jpg', {}))
+            .rejects.toThrow('Expected "test.jpg" to be an image, but received unknown file type.');
     });
 
     it('resolves with fetched image', async () => {