Merge pull request #3450 from overleaf/ta-error-handling-simple

Improve fetchJSON Response Handling

GitOrigin-RevId: b87a1947a1c0f0b2ee8b14bf3b80782aaf85ff2f
This commit is contained in:
Timothée Alby 2021-01-05 11:57:18 +01:00 committed by Copybot
parent 2f178f3aa9
commit 204d9a7138
2 changed files with 35 additions and 11 deletions

View file

@ -174,7 +174,7 @@ export function useFileTreeActionable() {
return syncDelete(projectId, found.type, found.entity._id).catch(
error => {
// throw unless 404
if (error.message !== '404') {
if (error.info.statusCode !== '404') {
throw error
}
}
@ -281,7 +281,7 @@ export function useFileTreeActionable() {
new CustomEvent('FileTreeReactBridge.openNewFileModal', {
detail: {
error: true,
data: error.message
data: error.info.responseBody
}
})
)

View file

@ -3,6 +3,7 @@
// - set the JSON content-type in the request headers
// - throw errors on non-ok response
// - parse JSON response body, unless response is empty
const OError = require('@overleaf/o-error')
export function getJSON(path, options) {
return fetchJSON(path, { ...options, method: 'GET' })
@ -25,7 +26,8 @@ export default function fetchJSON(
headers: {
...headers,
'Content-Type': 'application/json',
'X-Csrf-Token': window.csrfToken
'X-Csrf-Token': window.csrfToken,
Accept: 'application/json'
},
method
}
@ -35,14 +37,36 @@ export default function fetchJSON(
}
return fetch(path, options)
.then(response => {
if (!response.ok) throw new Error(response.status)
// get the response as text first as .json() fails on empty responses.
// (e.g. 204 responses)
return response.text()
.then(parseResponseBody)
.then(({ responseBody, response }) => {
if (!response.ok) {
throw new OError(response.statusText, {
statusCode: response.status,
responseBody,
response
})
.then(responseText => {
return responseText ? JSON.parse(responseText) : responseText
}
return responseBody
})
}
function parseResponseBody(response) {
const contentType = response.headers.get('Content-Type')
if (/application\/json/.test(contentType)) {
return response.json().then(json => {
return { responseBody: json, response }
})
} else if (
/text\/plain/.test(contentType) ||
/text\/html/.test(contentType)
) {
return response.text().then(text => {
return { responseBody: { message: text }, response }
})
} else {
// response body ignored as content-type is either not set (e.g. 204
// responses) or unsupported
return Promise.resolve({ responseBody: {}, response })
}
}