diff --git a/src/http/errors.ts b/src/http/errors.ts index 85c33f8..89d04ea 100644 --- a/src/http/errors.ts +++ b/src/http/errors.ts @@ -6,10 +6,18 @@ export class ApiError extends Error { } } -// 业务错误(code !== 0) +// 业务错误(后端 Code 为字符串,如 '200'/'500'/'401') export class BusinessError extends Error { - constructor(message: string, public readonly code: number) { + constructor(message: string, public readonly code: string) { super(message) this.name = 'BusinessError' } } + +// 登录态失效(HTTP 401 或业务码 401),触发踢回登录页 +export class AuthExpiredError extends Error { + constructor(message: string) { + super(message) + this.name = 'AuthExpiredError' + } +} diff --git a/src/http/index.ts b/src/http/index.ts index 1929be5..b1581e1 100644 --- a/src/http/index.ts +++ b/src/http/index.ts @@ -1,2 +1,2 @@ export { request } from './client' -export { ApiError, BusinessError } from './errors' +export { ApiError, BusinessError, AuthExpiredError } from './errors' diff --git a/tests/unit/http/errors.spec.ts b/tests/unit/http/errors.spec.ts new file mode 100644 index 0000000..2e552e8 --- /dev/null +++ b/tests/unit/http/errors.spec.ts @@ -0,0 +1,25 @@ +import { describe, it, expect } from 'vitest' +import { ApiError, BusinessError, AuthExpiredError } from '@/http/errors' + +describe('HTTP 错误类型', () => { + it('BusinessError.code 接受字符串业务码(后端 Code 为字符串)', () => { + const err = new BusinessError('用户未登录', '401') + expect(err).toBeInstanceOf(BusinessError) + expect(err.code).toBe('401') + expect(err.message).toBe('用户未登录') + expect(err.name).toBe('BusinessError') + }) + + it('AuthExpiredError 是独立错误类型,可被 catch 分流', () => { + const err = new AuthExpiredError('登录已过期') + expect(err).toBeInstanceOf(AuthExpiredError) + expect(err).toBeInstanceOf(Error) + expect(err.name).toBe('AuthExpiredError') + expect(err.message).toBe('登录已过期') + }) + + it('ApiError 保留 statusCode', () => { + const err = new ApiError('HTTP 404', 404) + expect(err.statusCode).toBe(404) + }) +})