import { RequestResponseError, type RequestResponse } from '../request.js'; import type { GraphqlErrorData, GraphqlErrorLike, GraphqlRequest, GraphqlResponseData } from './interfaces.js'; /** Graphql 错误 */ export class GraphqlError extends RequestResponseError implements GraphqlErrorData, GraphqlErrorLike { constructor(request: GraphqlRequest, response: RequestResponse, error: GraphqlErrorData) { super(response, undefined, error.message); this.name = 'GraphqlError'; this.request = request; Object.assign(this, error); } /** 原始请求 */ readonly request: GraphqlRequest; } /** 多个 Graphql 错误,默认包含第一个错误的信息,其他错误在 `errors` 字段中 */ export class GraphqlAggregateError extends GraphqlError { constructor(request: GraphqlRequest, response: RequestResponse, errors: GraphqlError[]) { if (errors.length === 0) throw new Error('No errors'); super(request, response, errors[0]!); this.name = 'GraphqlAggregateError'; this.errors = errors; } /** 所有错误 */ readonly errors: readonly GraphqlError[]; } /** 是否为 object */ function isObjectLike(value: unknown): value is object { return value != null && typeof value == 'object'; } /** 包装其他错误 */ export function wrapError( error: T, request: GraphqlRequest, response?: RequestResponse, ): T & GraphqlErrorLike { const err = ( error instanceof Error ? error : response ? new RequestResponseError(response, undefined, String(error)) : new Error(String((error as Error)?.message ?? error ?? '')) ) as T & GraphqlErrorLike; err.request = request; return err; } /** 创建响应异常 */ export function checkError( request: GraphqlRequest, response: RequestResponse, payload: GraphqlResponseData | null, ): GraphqlError[] | undefined { if (!isObjectLike(payload)) { throw new RequestResponseError(response, undefined, `Invalid response data, response body is not an object`); } const { errors, data } = payload; if (errors != null && !Array.isArray(errors)) { throw new RequestResponseError(response, undefined, `Invalid response payload, 'errors' should be an array`); } const errorList = []; if (errors) { for (let i = 0; i < errors.length; i++) { const data = errors[i]; if (!isObjectLike(data)) { throw new RequestResponseError( response, undefined, `Invalid response payload, 'errors[${i}]' should be an object`, ); } errorList.push(new GraphqlError(request, response, data)); } } if (!isObjectLike(data)) { if (errorList.length === 0) { throw new RequestResponseError( response, undefined, `Invalid response payload, 'data' should be presented while 'errors' is empty`, ); } if (errorList.length === 1) { throw errorList[0]!; } throw new GraphqlAggregateError(request, response, errorList); } if (errorList.length === 0) return undefined; return errorList; }