From 30d5eb980167e3504aa0ec31e90c325226eabb80 Mon Sep 17 00:00:00 2001 From: ekzyis Date: Fri, 13 Sep 2024 17:41:07 +0200 Subject: [PATCH] Catch s3 upload errors (#1400) * Catch s3 upload errors * Include file name in error message * More renaming from image to file --- api/resolvers/upload.js | 7 ++++--- components/file-upload.js | 24 +++++++++++++----------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/api/resolvers/upload.js b/api/resolvers/upload.js index e239ffe4..020c2bc9 100644 --- a/api/resolvers/upload.js +++ b/api/resolvers/upload.js @@ -29,11 +29,12 @@ export default { } } + // width and height is 0 for videos if (width * height > IMAGE_PIXELS_MAX) { throw new GqlInputError(`image must be less than ${IMAGE_PIXELS_MAX} pixels`) } - const imgParams = { + const fileParams = { type, size, width, @@ -44,10 +45,10 @@ export default { if (avatar) { if (!me) throw new GqlAuthenticationError() - imgParams.paid = undefined + fileParams.paid = undefined } - const upload = await models.upload.create({ data: { ...imgParams } }) + const upload = await models.upload.create({ data: { ...fileParams } }) return createPresignedPost({ key: String(upload.id), type, size }) } } diff --git a/components/file-upload.js b/components/file-upload.js index 25497153..8184d961 100644 --- a/components/file-upload.js +++ b/components/file-upload.js @@ -39,8 +39,8 @@ export const FileUpload = forwardRef(({ children, className, onSelect, onUpload, try { ({ data } = await getSignedPOST({ variables })) } catch (e) { - toaster.danger('error initiating upload: ' + e.message || e.toString?.()) onError?.({ ...variables, name: file.name, file }) + reject(e) return } @@ -58,10 +58,8 @@ export const FileUpload = forwardRef(({ children, className, onSelect, onUpload, if (!res.ok) { // TODO make sure this is actually a helpful error message and does not expose anything to the user we don't want - const err = res.statusText - toaster.danger('error uploading: ' + err) onError?.({ ...variables, name: file.name, file }) - reject(err) + reject(new Error(res.statusText)) return } @@ -96,16 +94,20 @@ export const FileUpload = forwardRef(({ children, className, onSelect, onUpload, onChange={async (e) => { const fileList = e.target.files for (const file of Array.from(fileList)) { - if (accept.indexOf(file.type) === -1) { - toaster.danger(`image must be ${accept.map(t => t.replace('image/', '').replace('video/', '')).join(', ')}`) + try { + if (accept.indexOf(file.type) === -1) { + throw new Error(`file must be ${accept.map(t => t.replace(/^(image|video)\//, '')).join(', ')}`) + } + if (onSelect) await onSelect?.(file, s3Upload) + else await s3Upload(file) + } catch (e) { + toaster.danger(`upload of '${file.name}' failed: ` + e.message || e.toString?.()) continue } - if (onSelect) await onSelect?.(file, s3Upload) - else await s3Upload(file) - // reset file input - // see https://bobbyhadz.com/blog/react-reset-file-input#reset-a-file-input-in-react - e.target.value = null } + // reset file input + // see https://bobbyhadz.com/blog/react-reset-file-input#reset-a-file-input-in-react + e.target.value = null }} />