Fix HEIC crash: skip unsupported images gracefully

Sharp in this container lacks HEIF support, causing the entire form
submission to fail when someone uploads a HEIC file. Wrap each file
conversion in try/catch so unsupported formats are skipped with a
warning and the message still goes through.

Also remove HEIC from the advertised accepted formats in the UI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chris 2026-06-16 21:44:37 -04:00
parent 14fc9df9d2
commit 699c5cbaa1
3 changed files with 9 additions and 5 deletions

View File

@ -148,7 +148,7 @@
<div class="control"> <div class="control">
<div id="dropzone"> <div id="dropzone">
<p><i class="fas fa-images"></i> Drag &amp; drop photos here, or <span class="has-text-info" style="text-decoration:underline;">browse</span></p> <p><i class="fas fa-images"></i> Drag &amp; drop photos here, or <span class="has-text-info" style="text-decoration:underline;">browse</span></p>
<p class="is-size-7 has-text-grey mt-1">JPEG · PNG · HEIC · WebP — max 10 MB each</p> <p class="is-size-7 has-text-grey mt-1">JPEG · PNG · WebP — max 10 MB each</p>
<input id="photoInput" type="file" name="photos" accept="image/*" multiple style="display:none;"> <input id="photoInput" type="file" name="photos" accept="image/*" multiple style="display:none;">
</div> </div>
<div id="photoPreview"></div> <div id="photoPreview"></div>

View File

@ -208,7 +208,7 @@
<div class="control"> <div class="control">
<div id="dropzone"> <div id="dropzone">
<p><i class="fas fa-images"></i> Drag &amp; drop photos here, or <span class="has-text-info" style="text-decoration:underline;">browse</span></p> <p><i class="fas fa-images"></i> Drag &amp; drop photos here, or <span class="has-text-info" style="text-decoration:underline;">browse</span></p>
<p class="is-size-7 has-text-grey mt-1">JPEG · PNG · HEIC · WebP — max 10 MB each</p> <p class="is-size-7 has-text-grey mt-1">JPEG · PNG · WebP — max 10 MB each</p>
<input id="photoInput" type="file" name="photos" accept="image/*" multiple style="display:none;"> <input id="photoInput" type="file" name="photos" accept="image/*" multiple style="display:none;">
</div> </div>
<div id="photoPreview"></div> <div id="photoPreview"></div>

View File

@ -174,9 +174,13 @@ apiRouter.post('/contact', upload.array('photos', 3), async (req, res) => {
const attachments = []; const attachments = [];
for (const file of (req.files || [])) { for (const file of (req.files || [])) {
const webpBuffer = await sharp(file.buffer).webp({ quality: 85 }).toBuffer(); try {
const baseName = path.parse(file.originalname).name; const webpBuffer = await sharp(file.buffer).webp({ quality: 85 }).toBuffer();
attachments.push({ filename: `${baseName}.webp`, content: webpBuffer, contentType: 'image/webp' }); const baseName = path.parse(file.originalname).name;
attachments.push({ filename: `${baseName}.webp`, content: webpBuffer, contentType: 'image/webp' });
} catch (err) {
console.warn(`[${new Date().toISOString()}] Skipping unsupported image ${file.originalname}: ${err.message}`);
}
} }
function formatDate(str) { function formatDate(str) {