zhou zhou
昨天 33bd4dd1f0e41131cd8e5bbf87204a1f0b72bb08
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { ApiStatus } from './status'
import { $t } from '@/locales'
class HttpError extends Error {
  constructor(message, code, options) {
    super(message)
    this.name = 'HttpError'
    this.code = code
    this.data = options?.data
    this.timestamp = /* @__PURE__ */ new Date().toISOString()
    this.url = options?.url
    this.method = options?.method
    this.status = options?.status
    this.contentType = options?.contentType
  }
  toLogData() {
    return {
      code: this.code,
      message: this.message,
      data: this.data,
      timestamp: this.timestamp,
      url: this.url,
      method: this.method,
      status: this.status,
      contentType: this.contentType,
      stack: this.stack
    }
  }
}
function resolveRequestUrl(config) {
  const baseURL = String(config?.baseURL || '').trim()
  const requestUrl = String(config?.url || '').trim()
  if (!baseURL && !requestUrl) {
    return void 0
  }
  if (!baseURL) {
    return requestUrl || void 0
  }
  if (!requestUrl) {
    return baseURL
  }
  const isAbsoluteBase = /^https?:\/\//i.test(baseURL)
  if (!isAbsoluteBase) {
    const normalizedBase = baseURL.replace(/\/+$/, '')
    const normalizedUrl = requestUrl.replace(/^\/+/, '')
    if (!normalizedBase) {
      return requestUrl
    }
    if (!normalizedUrl) {
      return normalizedBase
    }
    return `${normalizedBase}/${normalizedUrl}`
  }
  try {
    const origin = globalThis?.location?.origin || 'http://localhost'
    const normalizedBase = new URL(baseURL, origin)
    return new URL(requestUrl, normalizedBase).toString()
  } catch {
    const normalizedBase = baseURL.replace(/\/+$/, '')
    const normalizedUrl = requestUrl.replace(/^\/+/, '')
    if (!normalizedBase) {
      return requestUrl
    }
    if (!normalizedUrl) {
      return normalizedBase
    }
    return `${normalizedBase}/${normalizedUrl}`
  }
}
const getErrorMessage = (status) => {
  const errorMap = {
    [ApiStatus.unauthorized]: 'httpMsg.unauthorized',
    [ApiStatus.forbidden]: 'httpMsg.forbidden',
    [ApiStatus.notFound]: 'httpMsg.notFound',
    [ApiStatus.methodNotAllowed]: 'httpMsg.methodNotAllowed',
    [ApiStatus.requestTimeout]: 'httpMsg.requestTimeout',
    [ApiStatus.internalServerError]: 'httpMsg.internalServerError',
    [ApiStatus.badGateway]: 'httpMsg.badGateway',
    [ApiStatus.serviceUnavailable]: 'httpMsg.serviceUnavailable',
    [ApiStatus.gatewayTimeout]: 'httpMsg.gatewayTimeout'
  }
  return $t(errorMap[status] || 'httpMsg.internalServerError')
}
function isRequestCancelled(error) {
  const message = String(error?.message || '').toLowerCase()
  return (
    error?.code === 'ERR_CANCELED' ||
    error?.name === 'CanceledError' ||
    error?.name === 'AbortError' ||
    message.includes('canceled') ||
    message.includes('cancelled') ||
    message.includes('aborted') ||
    message.includes('请求已取消')
  )
}
function handleError(error) {
  const requestConfig = error.config
  if (isRequestCancelled(error)) {
    throw new HttpError($t('httpMsg.requestCancelled'), 'REQUEST_CANCELLED', {
      url: resolveRequestUrl(requestConfig),
      method: requestConfig?.method?.toUpperCase()
    })
  }
  const statusCode = error.response?.status
  const errorMessage = error.response?.data?.msg || error.message
  if (!error.response) {
    throw new HttpError($t('httpMsg.networkError'), ApiStatus.error, {
      url: resolveRequestUrl(requestConfig),
      method: requestConfig?.method?.toUpperCase()
    })
  }
  const message = statusCode
    ? getErrorMessage(statusCode)
    : errorMessage || $t('httpMsg.requestFailed')
  throw new HttpError(message, statusCode || ApiStatus.error, {
    data: error.response.data,
    url: resolveRequestUrl(requestConfig),
    method: requestConfig?.method?.toUpperCase(),
    status: statusCode,
    contentType: error.response?.headers?.['content-type']
  })
}
function showError(error, showMessage = true) {
  if (error.code === 'REQUEST_CANCELLED') {
    return
  }
  if (showMessage) {
    ElMessage.error(error.message)
  }
  console.error('[HTTP Error]', error.toLogData())
}
function showSuccess(message, showMessage = true) {
  if (showMessage) {
    ElMessage.success(message)
  }
}
const isHttpError = (error) => {
  return error instanceof HttpError
}
export { HttpError, handleError, isHttpError, resolveRequestUrl, showError, showSuccess }