Fix host upload: handle multer errors as JSON, pre-create upload-tmp dir; v2.0.41
Publish Container / docker (push) Successful in 15m21s

If multer failed to write the temp file (e.g. data-volume permission issue),
the error was propagating unhandled through Express, returning a non-JSON 500
that the client couldn't parse — showing only "Upload failed." with no details.

Changes:
- Import mkdir and pre-create UPLOAD_TEMP_DIR on startup (non-blocking)
- Wrap upload.single('file') in a callback so multer errors return JSON
  responses with the actual message instead of a bare HTML 500

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 4.6 committed 2026-09-22 07:49:00 -04:00
1 parent 600c450eff
commit 8ba300eddc
2 files changed
+16 -3

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "siteforge", "name": "siteforge",
"private": true, "private": true,
"version": "2.0.40", "version": "2.0.41",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
+15 -2
View File
@@ -1,5 +1,5 @@
import { randomUUID } from 'node:crypto' import { randomUUID } from 'node:crypto'
import { readFile, writeFile, unlink } from 'node:fs/promises' import { readFile, writeFile, unlink, mkdir } from 'node:fs/promises'
import path from 'node:path' import path from 'node:path'
import multer from 'multer' import multer from 'multer'
import rateLimit from 'express-rate-limit' import rateLimit from 'express-rate-limit'
@@ -231,6 +231,10 @@ const otpRateLimiter = rateLimit({
// ── Route registration ──────────────────────────────────────────────────── // ── Route registration ────────────────────────────────────────────────────
export function register(app) { export function register(app) {
// Ensure temp upload dir exists (non-blocking; created well before any upload)
mkdir(UPLOAD_TEMP_DIR, { recursive: true }).catch(err => {
console.error('[nuggets-upload] could not create upload-tmp dir:', err.message)
})
// ── Host auth ───────────────────────────────────────────────────────── // ── Host auth ─────────────────────────────────────────────────────────
app.get('/api/nuggets-upload/me', async (req, res) => { app.get('/api/nuggets-upload/me', async (req, res) => {
@@ -389,7 +393,16 @@ export function register(app) {
// ── Episode upload (audio file + metadata) ─────────────────────────── // ── Episode upload (audio file + metadata) ───────────────────────────
app.post('/api/nuggets-upload/upload', requireHostAuth, upload.single('file'), async (req, res) => { app.post('/api/nuggets-upload/upload', requireHostAuth, (req, res, next) => {
upload.single('file')(req, res, err => {
if (!err) return next()
if (err.code === 'LIMIT_FILE_SIZE') {
return res.status(400).json({ message: 'File exceeds the 500 MB limit.' })
}
console.error('[nuggets-upload] multer error:', err.message)
return res.status(500).json({ message: `File upload error: ${err.message}` })
})
}, async (req, res) => {
if (!req.file) { if (!req.file) {
res.status(400).json({ message: 'No file received.' }) res.status(400).json({ message: 'No file received.' })
return return