https://sonarly.com/issue/14764?type=bug Uploading certain PDFs via the `UploadFilesFieldFile` mutation crashes with an unhandled SAX XML parsing error ("Unclosed root tag") thrown by the `@file-type/pdf` plugin during file type detection. Fix: Wrapped the `fileParser.fromBuffer(file)` call in `extractFileInfo` with a try-catch to handle errors thrown by the `@file-type/pdf` plugin's internal SAX XML parser. **What changed:** In `extract-file-info.utils.ts`: Instead of `const { ext, mime } = (await fileParser.fromBuffer(file)) ?? {}`, the result is now obtained inside a try-catch. When `fromBuffer` throws (e.g., "Unclosed root tag" from the SAX parser parsing malformed XMP metadata inside a PDF), the error is caught and the function falls through to extension-based detection — the same path it takes when `fromBuffer` returns `undefined`. This converts an unhandled 500 error into the existing structured error handling: - For non-detectable types (txt, csv, json, etc.): returns extension-based MIME type as before - For detectable types (pdf, png, etc.): throws a `FileStorageException` with a user-friendly message ("content doesn't match extension") — which is properly handled by the GraphQL error filters In `extract-file-info.utils.spec.ts`: Added two tests: 1. Verifies that when `fromBuffer` throws, the function gracefully falls back to extension-based detection for non-detectable types 2. Verifies that when `fromBuffer` throws for a detectable type (pdf), the function throws a `FileStorageException` (not the raw SAX error) **Why not fix deeper:** The root bug is in `@file-type/pdf` (third-party library) which doesn't catch SAX parser errors for non-PDF XML content. The `file-type` core's `fromTokenizer` also only catches `EndOfStreamError` and `ParserHardLimitError`. Both are outside this codebase. This defensive catch at the call site is the appropriate pattern.
Run yarn dev while server running on port 3000