From 9f397a8982182036dec30f2e08e7d5d3c717fc45 Mon Sep 17 00:00:00 2001 From: cuixiaorui Date: Thu, 25 Jan 2024 23:59:59 +0800 Subject: [PATCH] refactor: exception handling and HTTP response in API --- apps/api/src/app/exception.fliter.ts | 23 ++++++++++------- apps/api/src/app/transform.interceptor.ts | 4 +-- apps/client/api/auth.ts | 25 +++--------------- apps/client/api/{courses.ts => course.ts} | 4 +++ apps/client/api/http.ts | 31 ++++++++++++++++++----- apps/client/pages/Courses.vue | 9 ++----- apps/client/store/course.ts | 2 +- apps/client/utils/token.ts | 15 +++++++++++ 8 files changed, 66 insertions(+), 47 deletions(-) rename apps/client/api/{courses.ts => course.ts} (76%) create mode 100644 apps/client/utils/token.ts diff --git a/apps/api/src/app/exception.fliter.ts b/apps/api/src/app/exception.fliter.ts index c087ef3a2..10ac1654f 100644 --- a/apps/api/src/app/exception.fliter.ts +++ b/apps/api/src/app/exception.fliter.ts @@ -5,20 +5,25 @@ import { HttpException, } from '@nestjs/common'; -import { Request, Response } from 'express'; - @Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter { catch(exception: HttpException, host: ArgumentsHost) { const ctx = host.switchToHttp(); - const response = ctx.getResponse(); - const request = ctx.getRequest(); + const response = ctx.getResponse(); const status = exception.getStatus(); - const message = exception.getResponse() as any; - response.status(status).json({ - code: status, - data: null, + + const message = exception.message + ? exception.message + : `${status >= 500 ? 'Service Error' : 'Client Error'}`; + + const errorResponse = { + data: {}, message, - }); + code: -1, + }; + + response.status(status); + response.header('Content-Type', 'application/json; charset=utf-8'); + response.send(errorResponse); } } diff --git a/apps/api/src/app/transform.interceptor.ts b/apps/api/src/app/transform.interceptor.ts index c30bda8b8..9300e164d 100644 --- a/apps/api/src/app/transform.interceptor.ts +++ b/apps/api/src/app/transform.interceptor.ts @@ -14,8 +14,8 @@ export class TransformInterceptor implements NestInterceptor { map((data) => { return { data, - code: 200, - message: '', + code: 1, + message: 'Request successful', }; }), ); diff --git a/apps/client/api/auth.ts b/apps/client/api/auth.ts index 7d885c1f3..9c1451e3d 100644 --- a/apps/client/api/auth.ts +++ b/apps/client/api/auth.ts @@ -1,4 +1,5 @@ import { type ErrorVo, isError } from "./common"; +import { http } from "./http"; interface LoginDto { phone: string; @@ -17,31 +18,13 @@ interface SignUpDto extends LoginDto { interface LoginVo { token: string; - user: UserInfo + user: UserInfo; } export async function login(dto: LoginDto) { - const message = useMessage(); - const { data } = await useFetchPlus("/auth/login", { - body: dto, - method: "post", - }); - if (isError(data.value)) { - message.error(data.value.message); - return; - } - return data.value as LoginVo; + return await http.post("/auth/login", dto); } export async function signUp(dto: SignUpDto) { - const message = useMessage(); - const { data } = await useFetchPlus("/auth/signup", { - body: dto, - method: "post", - }); - if (isError(data.value)) { - message.error(data.value.message); - return; - } - return data.value as LoginVo; + return await http.post("/auth/signup", dto); } diff --git a/apps/client/api/courses.ts b/apps/client/api/course.ts similarity index 76% rename from apps/client/api/courses.ts rename to apps/client/api/course.ts index 3013534fd..69bbab75e 100644 --- a/apps/client/api/courses.ts +++ b/apps/client/api/course.ts @@ -8,3 +8,7 @@ export async function fetchCourse(courseId: number) { export async function fetchNextCourse(courseId: number) { return await http.get(`/courses/${courseId}/next`); } + +export async function fetchCourses() { + return await http.get("/courses"); +} diff --git a/apps/client/api/http.ts b/apps/client/api/http.ts index 635465b44..8b5b3739e 100644 --- a/apps/client/api/http.ts +++ b/apps/client/api/http.ts @@ -1,5 +1,6 @@ import type { AxiosInstance, AxiosResponse } from "axios"; import axios from "axios"; +import { checkHaveToken, getToken } from "~/utils/token"; const isProd = process.env.NODE_ENV === "production"; @@ -11,19 +12,35 @@ export const http: AxiosInstance = axios.create({ headers: { "Content-Type": "application/json" }, }); -// http.interceptors.request.use((config) => { -// if (checkHaveToken()) config.headers.Authorization = `Bearer ${getToken()}`; +http.interceptors.request.use((config) => { + if (checkHaveToken()) config.headers.Authorization = `Bearer ${getToken()}`; -// return config; -// }); + return config; +}); http.interceptors.response.use( (response: AxiosResponse) => { - const { status, statusText, data } = response; + const { code, message, data } = response.data; - return data; + if (code === 1) { + return data; + } else { + console.error(message); + return Promise.reject(new Error(message)); + } }, (error) => { - // TODO 后面在统一处理 + if (error.response.status) { + switch (error.response.status) { + case 400: + console.error(error.message); + break; + case 401: + // TODO 跳转到登录 + console.error(error.message, "跳转到登录") + break; + } + return Promise.reject(error); + } } ); diff --git a/apps/client/pages/Courses.vue b/apps/client/pages/Courses.vue index 2372dd4f6..99423d037 100644 --- a/apps/client/pages/Courses.vue +++ b/apps/client/pages/Courses.vue @@ -29,14 +29,9 @@ diff --git a/apps/client/store/course.ts b/apps/client/store/course.ts index ee1208276..ba336931d 100644 --- a/apps/client/store/course.ts +++ b/apps/client/store/course.ts @@ -1,6 +1,6 @@ import { defineStore } from "pinia"; import { ref } from "vue"; -import { fetchCourse, fetchNextCourse } from "~/api/courses"; +import { fetchCourse, fetchNextCourse } from "~/api/course"; interface Statement { id: number; diff --git a/apps/client/utils/token.ts b/apps/client/utils/token.ts new file mode 100644 index 000000000..9fac16ced --- /dev/null +++ b/apps/client/utils/token.ts @@ -0,0 +1,15 @@ +export function getToken() { + return localStorage.getItem('token') +} + +export function checkHaveToken() { + return getToken() +} + +export function setToken(token: string) { + localStorage.setItem('token', token) +} + +export function cleanToken() { + localStorage.removeItem('token') +}