Files
botpress--botpress/integrations/googledrive/src/error-handling.ts
T
2026-07-13 13:34:48 +08:00

64 lines
2.2 KiB
TypeScript

import { createAsyncFnWrapperWithErrorRedaction, defaultErrorRedactor } from '@botpress/common'
import { z } from '@botpress/sdk'
import { Common } from 'googleapis'
import * as bp from '.botpress'
export const wrapWithTryCatch = createAsyncFnWrapperWithErrorRedaction(defaultErrorRedactor)
const errorDetailSchema = z.object({
domain: z.string(),
reason: z.string(),
message: z.string(),
})
type ErrorDetail = z.infer<typeof errorDetailSchema>
// For some reason, the Google API typing for GaxiosError does not correspond
// to the actual error object returned by the API. It is missing the `errors`
// field which contains the actual error messages. This type is a workaround
// to properly type the error object.
export type AggregateGAxiosError = Common.GaxiosError & { errors: ErrorDetail[] }
export const isGaxiosError = (error: unknown): error is AggregateGAxiosError => {
return (
error instanceof Error &&
'errors' in error &&
Array.isArray(error['errors']) &&
error['errors'].every((err) => errorDetailSchema.safeParse(err).success)
)
}
export type SubscriptionRateLimitError = AggregateGAxiosError // No discriminant
const SUBSCRIPTION_RATE_LIMIT_ERR_REASON = 'subscriptionRateLimitExceeded'
export const isSubscriptionRateLimitError = (error: unknown): error is SubscriptionRateLimitError => {
if (!isGaxiosError(error)) {
return false
}
return error.status === 403 && error.errors.some((err) => err.reason === SUBSCRIPTION_RATE_LIMIT_ERR_REASON)
}
export type NotFoundError = AggregateGAxiosError // No discriminant
export const isNotFoundError = (error: unknown): error is NotFoundError => {
if (!isGaxiosError(error)) {
return false
}
return error.status === 404
}
export const handleRateLimitError = async (e: unknown, logger?: bp.Logger): Promise<undefined> => {
if (!isSubscriptionRateLimitError(e)) {
throw e
}
if (logger) {
logger.forBot().warn('Subscription rate limit exceeded. Retry operation later.')
}
return undefined
}
export const handleNotFoundError = async (e: unknown, logger?: bp.Logger): Promise<undefined> => {
if (!isNotFoundError(e)) {
throw e
}
if (logger) {
logger.forBot().error(e.errors.map((err) => err.message).join('\n'))
}
return undefined
}