86 lines
2.5 KiB
TypeScript
86 lines
2.5 KiB
TypeScript
import type { Hooks } from 'ky'
|
|
import { isHTTPError } from 'ky'
|
|
import { extractErrorMessage, normalizeError } from './error'
|
|
import { emitHttpError } from './http-error'
|
|
import { emitHttpToast } from './http-toast'
|
|
import { emitForceLogout } from './session'
|
|
import { tokenService } from './token'
|
|
|
|
export function createHooks(): Hooks {
|
|
return {
|
|
beforeRequest: [
|
|
({ request }) => {
|
|
const token = tokenService.getToken()
|
|
const url = request.url
|
|
const shouldAttachToken = !url.includes('/Auth/login')
|
|
|
|
if (token && shouldAttachToken) {
|
|
request.headers.set('Authorization', `Bearer ${token}`)
|
|
}
|
|
},
|
|
],
|
|
beforeError: [
|
|
({ request, options, error }) => {
|
|
const normalized = normalizeError(error)
|
|
|
|
if (normalized.name === 'CanceledRequestError') {
|
|
return normalized
|
|
}
|
|
|
|
const requestUrl = request.url
|
|
const isLoginRequest = requestUrl.includes('/Auth/login')
|
|
const silentToast = Boolean(options.context.silentToast)
|
|
const status = isHTTPError(error) ? error.response.status : undefined
|
|
|
|
switch (status) {
|
|
case 401: {
|
|
if (requestUrl.includes('/Auth/login')) break
|
|
|
|
const hasAuthHeader = request.headers.has('Authorization')
|
|
if (hasAuthHeader) {
|
|
tokenService.clearToken()
|
|
const backendMessage = isHTTPError(error) ? extractErrorMessage(error.data) : undefined
|
|
emitForceLogout({ message: backendMessage })
|
|
}
|
|
break
|
|
}
|
|
case 403: {
|
|
emitHttpError({ status, message: normalized.message })
|
|
break
|
|
}
|
|
case 404: {
|
|
emitHttpError({ status, message: normalized.message })
|
|
break
|
|
}
|
|
case 500: {
|
|
break
|
|
}
|
|
case 503: {
|
|
emitHttpError({ status, message: normalized.message })
|
|
break
|
|
}
|
|
default:
|
|
}
|
|
|
|
const shouldToast =
|
|
!silentToast &&
|
|
!isLoginRequest &&
|
|
status !== 401 &&
|
|
status !== 403 &&
|
|
status !== 404 &&
|
|
status !== 503 &&
|
|
(status === 500 || !status || (typeof status === 'number' && status >= 500))
|
|
|
|
if (shouldToast) {
|
|
emitHttpToast({
|
|
level: status ? 'error' : 'warning',
|
|
message: normalized.message,
|
|
})
|
|
}
|
|
|
|
return normalized
|
|
},
|
|
],
|
|
}
|
|
}
|