Fix failed media uploads bricking the frontend

The upload call hid errors and the entity normaliser lets them pass
through as well (assuming it must be an already "correctly" formatted
legacy qvitter response), which led to errors being added to the the
draft as if it was a valid attachment object.
On later use of this error exceptions occur breaking the frontend and
due to being saved as part of a draft this could only be recovered by
clearing local client data.

Fixes: #339
This commit is contained in:
Oneric 2025-10-18 00:00:00 +00:00
commit 7e4d381af1
2 changed files with 25 additions and 16 deletions

View file

@ -42,8 +42,14 @@ const mediaUpload = {
.then((fileData) => {
self.$emit('uploaded', fileData)
self.decreaseUploadCount()
}, (error) => {
self.$emit('upload-failed', 'default')
}, (error) => {
var msg = typeof error === "string" ? error : error.message
if (msg) {
self.$emit('upload-failed', 'message', [msg])
} else {
self.$emit('upload-failed', 'default')
}
console.warn(`Failed to upload media: ${error}`)
self.decreaseUploadCount()
})
},

View file

@ -124,6 +124,21 @@ let fetch = (url, options) => {
return oldfetch(fullUrl, options)
}
// TOOD: check if it is safe for all fetch() calls and can be directly integrated above
const getJsonIfSuccess = (response, url, options) => {
return new Promise((resolve, reject) => response.json()
.then((json) => {
if (!response.ok) {
return reject(new StatusCodeError(response.status, json, { url, options }, response))
}
return resolve(json)
})
.catch((error) => {
return reject(new StatusCodeError(response.status, error, { url, options }, response))
})
)
}
const promisedRequest = ({ method, url, params, payload, credentials, headers = {} }) => {
const options = {
method,
@ -148,19 +163,7 @@ const promisedRequest = ({ method, url, params, payload, credentials, headers =
}
}
return fetch(url, options)
.then((response) => {
return new Promise((resolve, reject) => response.json()
.then((json) => {
if (!response.ok) {
return reject(new StatusCodeError(response.status, json, { url, options }, response))
}
return resolve(json)
})
.catch((error) => {
return reject(new StatusCodeError(response.status, error, { url, options }, response))
})
)
})
.then((response) => getJsonIfSuccess(response))
}
const updateNotificationSettings = ({ credentials, settings }) => {
@ -988,7 +991,7 @@ const uploadMedia = ({ formData, credentials }) => {
method: 'POST',
headers: authHeaders(credentials)
})
.then((data) => data.json())
.then((response) => getJsonIfSuccess(response, MASTODON_MEDIA_UPLOAD_URL, {}))
.then((data) => parseAttachment(data))
}