From 3446954648f422c2cb4942240601b0ac905d66f7 Mon Sep 17 00:00:00 2001 From: Astrian Zheng Date: Sun, 12 Jan 2025 08:02:37 +1100 Subject: [PATCH] feat: enhance error handling in /payer route with detailed context and add ABN format validation --- backend/src/app.ts | 23 +++++++++++++++++------ backend/src/types/HttpError.ts | 9 ++++++++- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/backend/src/app.ts b/backend/src/app.ts index 85a3902..648d71e 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -19,7 +19,9 @@ app.use(async (ctx, next) => { } catch (e) { if (e instanceof HttpError) { ctx.status = e.status - ctx.body = JSON.stringify({ error: e.message }) + let errorBody: { error: string, context?: string[] } = { error: e.message } + if (e.context) errorBody['context'] = e.context + ctx.body = JSON.stringify(errorBody) } else { console.log(e) ctx.status = 500 @@ -28,6 +30,7 @@ app.use(async (ctx, next) => { } }) +// 具体路由 app.use(route.get('/', (ctx) => { ctx.body = 'Hello World' })) @@ -37,21 +40,29 @@ app.use(route.post('/payer', async (ctx) => { // 验证必填字段 // 字段缺失时 - if (!ctx.request.body) throw new HttpError(ErrorDescEnum.required_fields_missing, 400) + if (!ctx.request.body) throw new HttpError(ErrorDescEnum.required_fields_missing, 400, ['name', 'address', 'email']) // 有字段,但为空时 const { name, address, email, abn } = ctx.request.body - if (!name || !address || !email) throw new HttpError(ErrorDescEnum.required_fields_missing, 400) + let emptyFields = [] + if (!name) emptyFields.push('name') + if (!address) emptyFields.push('address') + if (!email) emptyFields.push('email') + if (emptyFields.length > 0) throw new HttpError(ErrorDescEnum.required_fields_missing, 400, emptyFields) // 验证地址格式,格式应为 string[],最多两行 - if (!Array.isArray(address) || address.length > 2 || address.length <= 0) throw new HttpError(ErrorDescEnum.invalid_field_format, 400) + if (!Array.isArray(address) || address.length > 2 || address.length <= 0) throw new HttpError(ErrorDescEnum.invalid_field_format, 400, ['address']) // 名字应为字符串 - if (typeof name !== 'string') throw new HttpError(ErrorDescEnum.invalid_field_format, 400) + if (typeof name !== 'string') throw new HttpError(ErrorDescEnum.invalid_field_format, 400, ['name']) // 验证邮箱格式 const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ - if (!emailRegex.test(email)) throw new HttpError(ErrorDescEnum.invalid_field_format, 400) + if (!emailRegex.test(email)) throw new HttpError(ErrorDescEnum.invalid_field_format, 400, ['email']) + + // 验证 ABN 格式 + const abnRegex = /^\d{11}$/ + if (abn && !abnRegex.test(abn)) throw new HttpError(ErrorDescEnum.invalid_field_format, 400, ['abn']) // 创建新的付款人 await func.createPayer(name, address, email, abn) diff --git a/backend/src/types/HttpError.ts b/backend/src/types/HttpError.ts index c767f44..88347f0 100644 --- a/backend/src/types/HttpError.ts +++ b/backend/src/types/HttpError.ts @@ -7,16 +7,23 @@ class HttpError extends Error { * 创建一个新的 HTTP 错误。 * @param message 错误的消息。 * @param status 错误的状态码。 + * @param context 错误的上下文。 */ - constructor(message: ErrorDescEnum, status: 400 | 401 | 403 | 404 | 500) { + constructor(message: ErrorDescEnum, status: 400 | 401 | 403 | 404 | 500, context?: string[]) { super(message); this.status = status; + if (context) this.context = context; } /** * 错误的状态码。 */ status: 400 | 401 | 403 | 404 | 500; + + /** + * 错误上下文,一般指示错误适用的字段。 + */ + context?: string[]; } /**