Javascript Fetch:如果状态不正常,是否拒绝承诺并捕获错误?
下面是我要说的:Javascript Fetch:如果状态不正常,是否拒绝承诺并捕获错误?,javascript,redux,fetch-api,Javascript,Redux,Fetch Api,下面是我要说的: import 'whatwg-fetch'; function fetchVehicle(id) { return dispatch => { return dispatch({ type: 'FETCH_VEHICLE', payload: fetch(`http://swapi.co/api/vehicles/${id}/`) .then(status)
import 'whatwg-fetch';
function fetchVehicle(id) {
return dispatch => {
return dispatch({
type: 'FETCH_VEHICLE',
payload: fetch(`http://swapi.co/api/vehicles/${id}/`)
.then(status)
.then(res => res.json())
.catch(error => {
throw(error);
})
});
};
}
function status(res) {
if (!res.ok) {
return Promise.reject()
}
return res;
}
编辑:承诺不会被拒绝,这就是我想弄明白的
我在Redux中使用此选项。承诺在出现网络错误时,仅使用TypeError拒绝。因为4xx和5xx响应不是网络错误,所以没有什么可捕获的。您需要自己抛出一个错误才能使用Promise\catch
A方便地提供了,它告诉您请求是否成功。像这样的事情应该可以做到:
fetch(url).then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error('Something went wrong');
}
})
.then((responseJson) => {
// Do something with the response
})
.catch((error) => {
console.log(error)
});
感谢大家的帮助,拒绝了
中的承诺。catch()
解决了我的问题:
export function fetchVehicle(id) {
return dispatch => {
return dispatch({
type: 'FETCH_VEHICLE',
payload: fetch(`http://swapi.co/api/vehicles/${id}/`)
.then(status)
.then(res => res.json())
.catch(error => {
return Promise.reject()
})
});
};
}
function status(res) {
if (!res.ok) {
throw new Error(res.statusText);
}
return res;
}
我刚刚检查了响应对象的状态:
$promise.then( function successCallback(response) {
console.log(response);
if (response.status === 200) { ... }
});
对我来说,
fny的回答真的很全面。因为fetch不是抛出错误,所以我们需要自己抛出/处理错误。
使用async/await发布我的解决方案。我认为它更具前瞻性和可读性
解决方案1:不抛出错误,自己处理错误
async _fetch(request) {
const fetchResult = await fetch(request); //Making the req
const result = await fetchResult.json(); // parsing the response
if (fetchResult.ok) {
return result; // return success object
}
const responseError = {
type: 'Error',
message: result.message || 'Something went wrong',
data: result.data || '',
code: result.code || '',
};
const error = new Error();
error.info = responseError;
return (error);
}
在这里,如果我们得到一个错误,我们正在构建一个错误对象,纯JS对象并返回它,缺点是我们需要在外部处理它。
如何使用:
const userSaved = await apiCall(data); // calling fetch
if (userSaved instanceof Error) {
debug.log('Failed saving user', userSaved); // handle error
return;
}
debug.log('Success saving user', userSaved); // handle success
解决方案2:使用try/catch抛出错误
async _fetch(request) {
const fetchResult = await fetch(request);
const result = await fetchResult.json();
if (fetchResult.ok) {
return result;
}
const responseError = {
type: 'Error',
message: result.message || 'Something went wrong',
data: result.data || '',
code: result.code || '',
};
let error = new Error();
error = { ...error, ...responseError };
throw (error);
}
这里我们抛出了我们创建的错误,因为错误只批准字符串,我创建了纯错误js对象,使用如下:
try {
const userSaved = await apiCall(data); // calling fetch
debug.log('Success saving user', userSaved); // handle success
} catch (e) {
debug.log('Failed saving user', userSaved); // handle error
}
解决方案3:使用客户错误
async _fetch(request) {
const fetchResult = await fetch(request);
const result = await fetchResult.json();
if (fetchResult.ok) {
return result;
}
throw new ClassError(result.message, result.data, result.code);
}
以及:
希望有帮助。2021打字稿答案
我要做的是编写一个fetch
包装器,它接受一个泛型,如果响应
是ok
它将自动.json()
并键入assert结果,否则包装器抛出响应
export const fetcher=async(输入:RequestInfo,init?:RequestInit)=>{
const response=等待获取(输入,初始化);
如果(!response.ok){
投掷反应;
}
返回response.json()作为承诺;
};
然后我将捕获错误并检查它们是否是响应的实例。这样,TypeScript就知道错误
具有响应
属性,例如状态
状态文本
正文
标题
等。我可以为每个4xx
5xx
状态代码应用自定义消息
试试看{
返回等待获取程序(“http://localhost:8080/login", {
方法:“张贴”,
标题:{
接受:“应用程序/json”,
“内容类型”:“应用程序/json”,
},
正文:JSON.stringify({email:user@example.com,密码:“passw0rd”}),
});
}捕获(错误){
if(响应的错误实例){
开关(错误状态){
案例401:
抛出新错误(“无效登录凭据”);
/* ... */
违约:
抛出新错误(`发生未知服务器错误:${Error.statusText}`);
}
}
抛出新错误(`Something出错:${Error.message | | Error}`);
}
如果出现类似网络错误的情况,则可以在响应的实例之外捕获,并使用更通用的消息进行检查,即
抛出新错误(`Something出错:${Error.message | | Error}`);
以下使用用户名和密码登录的示例演示了如何:
检查响应。确定
如果不正常,则拒绝
,而不是抛出错误
进一步处理来自服务器的任何错误提示,例如验证问题
您在catch
中抛出异常,但不catch
它。它确实到达catch
(它捕获它所连接的整个链中的所有拒绝),但是catch
回调不处理任何事情-它只会重新返回错误。用控制台替换抛出
。错误
左右。浏览器冻结?这绝对不应该发生。谢谢各位,我对这有点陌生,冰冻是由其他原因造成的。我认为这对我来说是一个问题,因为它将404视为一个成功的响应。我在拒绝这个承诺时遇到了一些麻烦,一旦我发现它应该是好的。更优秀的github.com/github/fetch/issues/203#issuecomment-14347675我没有找到属性“ok”,而是检查了response.status==200。为什么我不能从代码中判断抛出TypeError的原因?在控制台中,我看到一个例子是“net::ERR\u CONNECTION\u TIMED\u OUT”,但在另一个例子中是“(blocked:mixed content)”我不想对两者都做出相同的响应。此解决方案是否会停止在控制台中获取错误,例如401无效请求?当没有网络连接或服务器响应(例如,503 Service Temp)时,我们如何返回自定义响应。不可用
如果拒绝承诺的结果是类型错误
?如何读取捕获中的JSON?我从捕获块中需要的BE发送附加数据您也可以拒绝状态函数的承诺,如下所示:function status(res){if(!res.ok){return Promise.reject(res.statusText);}return res;}
或者实际上,您可以使用端点提供的消息拒绝承诺。或者,如果您对该响应进行jsonfy,然后使用从jsonfied响应中选择的属性返回拒绝的承诺,您也可以使用端点提供的消息拒绝承诺。这.catch(错误=>{返回承诺。拒绝()})
似乎毫无意义。为什么要抑制有用的错误
而用未定义的
来拒绝呢?@Vivek或者你也可以同样地抛出未定义的;
。我抱怨的不是拒绝,而是忽略了错误
。不过可能整个事情都应该忽略。@Vivek这可能会让我更痛苦e是有意义的,但这不是他们所做的。同样使用undefined
代替带有正确消息的错误是s
class ClassError extends Error {
constructor(message = 'Something went wrong', data = '', code = '') {
super();
this.message = message;
this.data = data;
this.code = code;
}
}
login() {
const url = "https://example.com/api/users/login";
const headers = {
Accept: "application/json",
"Content-Type": "application/json",
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify({
email: this.username,
password: this.password,
}),
})
.then((response) => {
// 1. check response.ok
if (response.ok) {
return response.json();
}
return Promise.reject(response); // 2. reject instead of throw
})
.then((json) => {
// all good, token is ready
this.store.commit("token", json.access_token);
})
.catch((response) => {
console.log(response.status, response.statusText);
// 3. get error messages, if any
response.json().then((json: any) => {
console.log(json);
})
});
},