This commit is contained in:
parent
f54b16641e
commit
3d12ec2e5f
@ -6,25 +6,28 @@ interface NetRequestParams {
|
||||
method: string
|
||||
queryParams?: any
|
||||
payload?: any
|
||||
additionalHeaders?: any
|
||||
additionalHeaders?: Record<string, string>
|
||||
}
|
||||
|
||||
interface NetErrorDetail {
|
||||
httpStatus: number
|
||||
response: Response | null
|
||||
code: number
|
||||
message: string
|
||||
data?: any
|
||||
}
|
||||
|
||||
export class NetError extends Error {
|
||||
public response: Response | null
|
||||
public code: number
|
||||
public message: string
|
||||
public httpStatus: number
|
||||
public data?: any
|
||||
|
||||
constructor({ code, message, httpStatus }: NetErrorDetail) {
|
||||
constructor({ response, code, message, data }: NetErrorDetail) {
|
||||
super(message)
|
||||
this.response = response
|
||||
this.code = code
|
||||
this.message = message
|
||||
this.httpStatus = httpStatus
|
||||
this.data = data
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,8 +36,8 @@ export class NetError extends Error {
|
||||
*/
|
||||
class NetToolBase {
|
||||
protected prefix: string
|
||||
protected headers: any
|
||||
protected getHeaders: () => any
|
||||
protected headers: Record<string, string>
|
||||
protected getHeaders: () => Record<string, string>
|
||||
protected logger: Logger
|
||||
protected requestId: string
|
||||
|
||||
@ -43,7 +46,7 @@ class NetToolBase {
|
||||
*
|
||||
* @param {Object} params - 构造函数参数。
|
||||
* @param {string} [params.prefix] - URL前缀。
|
||||
* @param {any} [params.headers] - 默认请求头。
|
||||
* @param {Record<string, string>} [params.headers] - 默认请求头。
|
||||
* @param {Function} [params.getHeaders] - 获取请求头的方法。
|
||||
* @param {string} [params.requestId] - 请求ID。
|
||||
*/
|
||||
@ -54,8 +57,8 @@ class NetToolBase {
|
||||
requestId,
|
||||
}: {
|
||||
prefix?: string
|
||||
headers?: any
|
||||
getHeaders?: () => any
|
||||
headers?: Record<string, string>
|
||||
getHeaders?: () => Record<string, string>
|
||||
requestId?: string
|
||||
} = {}) {
|
||||
this.prefix = prefix || ""
|
||||
@ -65,32 +68,67 @@ class NetToolBase {
|
||||
this.logger = logger.child({ requestId })
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个网络工具类实例。
|
||||
*
|
||||
* @param {Object} params - 构造函数参数。
|
||||
* @param {string} [params.prefix] - URL前缀。
|
||||
* @param {Record<string, string>} [params.headers] - 默认请求头。
|
||||
* @param {Function} [params.getHeaders] - 获取请求头的方法。
|
||||
* @param {string} [params.requestId] - 请求ID。
|
||||
* @returns 一个网络工具类实例。
|
||||
*/
|
||||
child({
|
||||
prefix,
|
||||
headers,
|
||||
getHeaders,
|
||||
requestId,
|
||||
}: {
|
||||
prefix?: string
|
||||
headers?: Record<string, string>
|
||||
getHeaders?: () => Record<string, string>
|
||||
requestId?: string
|
||||
} = {}) {
|
||||
return new NetToolBase({
|
||||
prefix: prefix || this.prefix,
|
||||
headers: headers || this.headers,
|
||||
getHeaders: getHeaders || this.getHeaders,
|
||||
requestId: requestId || this.requestId,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录响应详情并返回响应日志对象。
|
||||
* @param response - 响应对象。
|
||||
* @param method - 请求使用的HTTP方法。
|
||||
* @param headers - 请求头。
|
||||
* @param requestBody - 请求体。
|
||||
* @param responseBody - 响应体。
|
||||
* @param {string} url - 请求地址。
|
||||
* @param {string} method - 请求使用的HTTP方法。
|
||||
* @param {Record<string, string>} headers - 请求头。
|
||||
* @param {any} requestBody - 请求体。
|
||||
* @param {any} responseBody - 响应体。
|
||||
* @param {number} requestTime - 请求时间。
|
||||
* @param {Response} [response] - 响应对象。
|
||||
* @returns 响应日志对象。
|
||||
*/
|
||||
private logResponse(
|
||||
response: Response,
|
||||
url: string,
|
||||
method: string,
|
||||
headers: any,
|
||||
headers: Record<string, string>,
|
||||
requestBody: any,
|
||||
responseBody: any
|
||||
responseBody: any,
|
||||
requestTime: number,
|
||||
response?: Response
|
||||
) {
|
||||
const responseLog = {
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
url: response.url,
|
||||
ok: response?.ok,
|
||||
status: response?.status,
|
||||
statusText: response?.statusText,
|
||||
url,
|
||||
method: method,
|
||||
requestHeaders: headers,
|
||||
responseHeaders: response.headers,
|
||||
responseHeaders: response?.headers,
|
||||
requestBody,
|
||||
responseBody,
|
||||
requestTime,
|
||||
responseTime: new Date().getTime(),
|
||||
}
|
||||
this.logger.http(JSON.stringify(responseLog, null, 2))
|
||||
return responseLog
|
||||
@ -128,8 +166,9 @@ class NetToolBase {
|
||||
const headers = {
|
||||
...this.headers,
|
||||
...(await this.getHeaders()),
|
||||
...additionalHeaders,
|
||||
}
|
||||
...(additionalHeaders || {}),
|
||||
} as Record<string, string>
|
||||
|
||||
// 设置请求Header
|
||||
if (!(payload instanceof FormData)) {
|
||||
headers["Content-Type"] = "application/json"
|
||||
@ -138,43 +177,64 @@ class NetToolBase {
|
||||
// 处理请求数据
|
||||
const body = payload instanceof FormData ? payload : JSON.stringify(payload)
|
||||
|
||||
// 发送请求
|
||||
const res = await fetch(fullUrl, {
|
||||
method,
|
||||
body,
|
||||
headers,
|
||||
})
|
||||
// 获取响应数据
|
||||
let resData: any = null
|
||||
let resText: string = ""
|
||||
let res: Response
|
||||
// 开始计时
|
||||
const requestTime = new Date().getTime()
|
||||
|
||||
try {
|
||||
resText = await res.text()
|
||||
resData = JSON.parse(resText)
|
||||
} catch {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
// 记录响应
|
||||
this.logResponse(res, method, headers, payload, resData || resText)
|
||||
if (!res.ok) {
|
||||
if (resData?.message || resData?.msg) {
|
||||
throw new NetError({
|
||||
httpStatus: res.status,
|
||||
code: resData?.code,
|
||||
message: resData?.message || resData?.msg,
|
||||
})
|
||||
res = await fetch(fullUrl, {
|
||||
method,
|
||||
body,
|
||||
headers,
|
||||
})
|
||||
try {
|
||||
resText = await res.text()
|
||||
resData = JSON.parse(resText)
|
||||
} catch {
|
||||
/* empty */
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 网络请求异常,如请求超时、DNS解析失败、CORS请求被阻止等
|
||||
this.logResponse(
|
||||
fullUrl,
|
||||
method,
|
||||
headers,
|
||||
payload,
|
||||
resData || resText,
|
||||
requestTime
|
||||
)
|
||||
throw new NetError({
|
||||
httpStatus: res.status,
|
||||
code: res.status,
|
||||
message: resText || "网络响应异常",
|
||||
response: null,
|
||||
code: 1,
|
||||
message: error.message || "网络请求异常",
|
||||
})
|
||||
}
|
||||
// 记录响应
|
||||
this.logResponse(
|
||||
fullUrl,
|
||||
method,
|
||||
headers,
|
||||
payload,
|
||||
resData || resText,
|
||||
requestTime,
|
||||
res
|
||||
)
|
||||
// http 错误码异常
|
||||
if (!res.ok) {
|
||||
throw new NetError({
|
||||
response: res,
|
||||
code: resData.code || res.status,
|
||||
message: resData.message || resData.msg || resText || res.statusText,
|
||||
data: resData.data,
|
||||
})
|
||||
}
|
||||
// http 错误码正常,但解析异常
|
||||
if (!resData) {
|
||||
throw new NetError({
|
||||
httpStatus: res.status,
|
||||
response: res,
|
||||
code: 1,
|
||||
message: "解析响应数据异常",
|
||||
})
|
||||
@ -182,7 +242,7 @@ class NetToolBase {
|
||||
// 响应数据异常
|
||||
if ("code" in resData && resData.code !== 0) {
|
||||
throw new NetError({
|
||||
httpStatus: res.status,
|
||||
response: res,
|
||||
code: resData.code,
|
||||
message: resData.message || resData.msg || "网络请求失败",
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user