我们的API服务器返回带有错误响应的JSON数据。我找不到在错误处理方法上处理JSON数据的标准方法。我当前的解决方案是这样。它正在工作,但是我想在catch()方法中处理错误,而不是then();
let url = 'http://localhost:8080';
let data = {'field': 'value'};
fetch(url, {
method: 'PUT',
body: JSON.stringify(data),
credentials: 'same-origin',
mode: 'cors',
headers: {
'content-type': 'application/json',
'accept': 'application/json'
}
})
.then(res => {
if (res.status == 400) {
return res.json();
} else if (!res.ok) {
throw (res);
} else {
return res.json();
}
}).then(data => {
if (data.status == 400) {
throw (data);
}
return (data);
}).catch(err => {
if (err.status == 400) {
throw this.handleError(err);
} else {
throw new Error(`HTTP Error ${err.status}`);
}
});
这是来自服务器的JSON响应的示例。
{
"parameters": {
"type": {
"isEmpty": "Field is required and cannot be empty"
},
"from": {
"isEmpty": "Field is required and cannot be empty"
},
"to": {
"isEmpty": "Field is required and cannot be empty"
}
},
"title": "Invalid parameter",
"type": "/api/doc/invalid-parameter",
"status": 400,
"detail": "Invalid parameter"
}
答案 0 :(得分:1)
我会在fetch周围做一个薄薄的包装,它会引发> = 400个带有已解析主体的响应,否则会解析成功响应。
function parse(res) {
const contentType = res.headers.get('Content-Type') || '';
const isJson = contentType.includes('application/json');
return isJson ? res.json() : res;
}
async function throwOnError(res) {
if (res.status >= 400) {
const err = new Error(res.statusText || 'Internal Server Error');
err.status = res.status;
const parsedRes = await parse(res);
err.body = parsedRes;
throw err;
}
return res;
}
async function fetchWrapper({ method, url, data, headers }) {
const combinedHeaders = {
'Content-Type': 'application/json',
'Accept': 'application/json',
};
if (headers) {
Object.assign(combinedHeaders, headers);
}
const options = {
credentials: 'same-origin',
mode: 'cors',
method,
headers: combinedHeaders,
};
if (data) {
options.body = JSON.stringify(data);
}
return fetch(url, options)
.then(throwOnError)
.then(parse);
}
const queryParams = (params) =>
Object.keys(params)
.filter(k => params[k] !== null && typeof params[k] !== 'undefined')
.map(k => `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`)
.join('&');
export const appendUrlParams = (url, params) => (params ? `${url}?${queryParams(params)}` : url);
export const $get = (url, params, { ...options }) =>
fetchWrapper({ method: 'GET', url: appendUrlParams(url, params), ...options });
export const $del = (url, params, { ...options }) =>
fetchWrapper({ method: 'DELETE', url: appendUrlParams(url, params), ...options });
export const $post = (url, data, { ...options }) =>
fetchWrapper({ method: 'POST', url, data, ...options });
export const $put = (url, data, { ...options }) =>
fetchWrapper({ method: 'PUT', url, data, ...options });
例如
async function fetchSomething() {
try {
const res = await $get('someurl');
// Do something with successful `res`.
} catch (err) {
console.error(err);
// err.status -> the status of the response
// err.body -> the body of the response
}
}
或者,如果您愿意,可以使用then / catch。