reactjs - 使用 axios 处理 API 错误响应(多个文件)
问题描述
我是 React 的新手,我试图将我的 Axios http 实用程序分隔在不同的文件中。
如果我使用正确的凭据登录,它可以正常工作,但是当我尝试错误的凭据并且我的 API 响应带有 401(坏凭据)消息时,Axios 会执行该then()
方法而不是该catch()
方法。
axios.ts
import Axios from "axios";
const JSON_CONTENT_TYPE = "application/json";
// axios configuration
const axios = Axios.create({
baseURL: process.env.REACT_APP_API_URL,
responseType: "json"
});
// ... other requests handlers
export const post = <T = any>(
url: string,
body: any,
params?: any,
contentType = JSON_CONTENT_TYPE
) => {
return axios.post<T>(url, body, {
params,
headers: { "Content-Type": contentType }
});
};
登录适配器.ts
import { ILogin } from "../../model/login.model";
import * as Http from "../axios";
import * as StorageManager from "../storage-manager";
type TokenBody = {
id_token: string;
};
export const login = (credentials: ILogin) => {
return new Promise((resolve, reject) => {
Http.post<TokenBody>("/authenticate", credentials)
.then((resp) => {
// Stores jwt in local/session storage.
// HERE IS WHEN MY APP CRASHES, The error says 'resp is undefined' and THIS ERROR (not the response from my API) is caught by the catch method below.
StorageManager.setToken(resp.data.id_token, credentials.rememberMe);
// Does another request to get user info.
Http.get("/account").then(console.log);
resolve("Success");
})
.catch((error) => reject("Error, " + error.response.data)); // THIS SHOULD SEND THE ERROR MESSAGE TO LoginPage.tsx
});
};
登录页面.tsx
import { FormEvent, useState } from "react";
import "../../styles/LoginPage.css";
import * as LoginAdapter from "../../adapters/loginAdapters/login-adapter";
import { RouteComponentProps } from "react-router-dom";
const LoginPage = ({history}: RouteComponentProps) = {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [rememberMe, setRememberMe] = useState(false);
const submit = (e: FormEvent<HTMLFormElement>) => {
LoginAdapter.login({ email, password, rememberMe })
.then(() => {
history.push("/admin/courses");
})
.catch((error) => {
console.log(error);
});
e.preventDefault();
}
return (
<form onSubmit={submit}>
{/* <input ... email, password, and 'remember me' form fields.*/}
</form>
);
}
export default LoginPage;
当我直接从包中使用axios时。( import axios from "axios"
) 它工作得很好。但是我必须重写我的 api 端点、响应类型、拦截器等。我不知道为什么它不起作用,我错过了什么吗?
解决方案
我的拦截器是问题所在,我没有注意到错误处理程序应该返回一个带有拒绝原因的 Promise。
axios.interceptors.response.use(
(resp) => resp,
(error) => {
if (
error.response.status === 401 &&
error.response.config.url !== "/account"
) {
LoginAdapter.logout();
}
// before: <nothing>
// now:
return Promise.reject(error);
}
);
推荐阅读
- swift - 如何使用 SpriteKit AR 在 Swift 中的 SKScene 上创建叠加 SCNScene?
- javascript - axios 请求立即开始,而不是等待 axios.all
- javafx - JavaFX:具有多个阶段图标的应用程序
- java - 最佳实践:如何在运行时为测试设置配置文件
- spring - java.net.UnknownHostException - Zuul 和 Eureka 不能在 Docker 中工作
- python-3.x - 如何从 Javascript 变量中检索值
- nightmare - 无法获得有效的选择器来实现 I.click()
- javascript - 如何从定义 setInterval() 的另一个函数调用 clearInterval()(函数在同一个类中)
- scala - 使用 Map 替换 Spark 中的列值
- javascript -