File size: 13,049 Bytes
7d9f678
1
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { SupportedResponse } from \"./fetch-types\"\nimport { isObject } from \"./utils\"\nimport { Assert } from \"./type-utils\"\n\n/**\n * Error codes returned in responses from the API.\n */\nexport enum APIErrorCode {\n  Unauthorized = \"unauthorized\",\n  RestrictedResource = \"restricted_resource\",\n  ObjectNotFound = \"object_not_found\",\n  RateLimited = \"rate_limited\",\n  InvalidJSON = \"invalid_json\",\n  InvalidRequestURL = \"invalid_request_url\",\n  InvalidRequest = \"invalid_request\",\n  ValidationError = \"validation_error\",\n  ConflictError = \"conflict_error\",\n  InternalServerError = \"internal_server_error\",\n  ServiceUnavailable = \"service_unavailable\",\n}\n\n/**\n * Error codes generated for client errors.\n */\nexport enum ClientErrorCode {\n  RequestTimeout = \"notionhq_client_request_timeout\",\n  ResponseError = \"notionhq_client_response_error\",\n}\n\n/**\n * Error codes on errors thrown by the `Client`.\n */\nexport type NotionErrorCode = APIErrorCode | ClientErrorCode\n\n/**\n * Base error type.\n */\nabstract class NotionClientErrorBase<\n  Code extends NotionErrorCode\n> extends Error {\n  abstract code: Code\n}\n\n/**\n * Error type that encompasses all the kinds of errors that the Notion client will throw.\n */\nexport type NotionClientError =\n  | RequestTimeoutError\n  | UnknownHTTPResponseError\n  | APIResponseError\n\n// Assert that NotionClientError's `code` property is a narrow type.\n// This prevents us from accidentally regressing to `string`-typed name field.\ntype _assertCodeIsNarrow = Assert<NotionErrorCode, NotionClientError[\"code\"]>\n\n// Assert that the type of `name` in NotionErrorCode is a narrow type.\n// This prevents us from accidentally regressing to `string`-typed name field.\ntype _assertNameIsNarrow = Assert<\n  \"RequestTimeoutError\" | \"UnknownHTTPResponseError\" | \"APIResponseError\",\n  NotionClientError[\"name\"]\n>\n\n/**\n * @param error any value, usually a caught error.\n * @returns `true` if error is a `NotionClientError`.\n */\nexport function isNotionClientError(\n  error: unknown\n): error is NotionClientError {\n  return isObject(error) && error instanceof NotionClientErrorBase\n}\n\n/**\n * Narrows down the types of a NotionClientError.\n * @param error any value, usually a caught error.\n * @param codes an object mapping from possible error codes to `true`\n * @returns `true` if error is a `NotionClientError` with a code in `codes`.\n */\nfunction isNotionClientErrorWithCode<Code extends NotionErrorCode>(\n  error: unknown,\n  codes: { [C in Code]: true }\n): error is NotionClientError & { code: Code } {\n  return isNotionClientError(error) && error.code in codes\n}\n\n/**\n * Error thrown by the client if a request times out.\n */\nexport class RequestTimeoutError extends NotionClientErrorBase<ClientErrorCode.RequestTimeout> {\n  readonly code = ClientErrorCode.RequestTimeout\n  readonly name = \"RequestTimeoutError\"\n\n  constructor(message = \"Request to Notion API has timed out\") {\n    super(message)\n  }\n\n  static isRequestTimeoutError(error: unknown): error is RequestTimeoutError {\n    return isNotionClientErrorWithCode(error, {\n      [ClientErrorCode.RequestTimeout]: true,\n    })\n  }\n\n  static rejectAfterTimeout<T>(\n    promise: Promise<T>,\n    timeoutMS: number\n  ): Promise<T> {\n    return new Promise<T>((resolve, reject) => {\n      const timeoutId = setTimeout(() => {\n        reject(new RequestTimeoutError())\n      }, timeoutMS)\n\n      promise\n        .then(resolve)\n        .catch(reject)\n        .then(() => clearTimeout(timeoutId))\n    })\n  }\n}\n\ntype HTTPResponseErrorCode = ClientErrorCode.ResponseError | APIErrorCode\n\nclass HTTPResponseError<\n  Code extends HTTPResponseErrorCode\n> extends NotionClientErrorBase<Code> {\n  readonly name: string = \"HTTPResponseError\"\n  readonly code: Code\n  readonly status: number\n  readonly headers: SupportedResponse[\"headers\"]\n  readonly body: string\n\n  constructor(args: {\n    code: Code\n    status: number\n    message: string\n    headers: SupportedResponse[\"headers\"]\n    rawBodyText: string\n  }) {\n    super(args.message)\n    const { code, status, headers, rawBodyText } = args\n    this.code = code\n    this.status = status\n    this.headers = headers\n    this.body = rawBodyText\n  }\n}\n\nconst httpResponseErrorCodes: { [C in HTTPResponseErrorCode]: true } = {\n  [ClientErrorCode.ResponseError]: true,\n  [APIErrorCode.Unauthorized]: true,\n  [APIErrorCode.RestrictedResource]: true,\n  [APIErrorCode.ObjectNotFound]: true,\n  [APIErrorCode.RateLimited]: true,\n  [APIErrorCode.InvalidJSON]: true,\n  [APIErrorCode.InvalidRequestURL]: true,\n  [APIErrorCode.InvalidRequest]: true,\n  [APIErrorCode.ValidationError]: true,\n  [APIErrorCode.ConflictError]: true,\n  [APIErrorCode.InternalServerError]: true,\n  [APIErrorCode.ServiceUnavailable]: true,\n}\n\nexport function isHTTPResponseError(\n  error: unknown\n): error is UnknownHTTPResponseError | APIResponseError {\n  if (!isNotionClientErrorWithCode(error, httpResponseErrorCodes)) {\n    return false\n  }\n\n  type _assert = Assert<\n    UnknownHTTPResponseError | APIResponseError,\n    typeof error\n  >\n\n  return true\n}\n\n/**\n * Error thrown if an API call responds with an unknown error code, or does not respond with\n * a property-formatted error.\n */\nexport class UnknownHTTPResponseError extends HTTPResponseError<ClientErrorCode.ResponseError> {\n  readonly name = \"UnknownHTTPResponseError\"\n\n  constructor(args: {\n    status: number\n    message: string | undefined\n    headers: SupportedResponse[\"headers\"]\n    rawBodyText: string\n  }) {\n    super({\n      ...args,\n      code: ClientErrorCode.ResponseError,\n      message:\n        args.message ??\n        `Request to Notion API failed with status: ${args.status}`,\n    })\n  }\n\n  static isUnknownHTTPResponseError(\n    error: unknown\n  ): error is UnknownHTTPResponseError {\n    return isNotionClientErrorWithCode(error, {\n      [ClientErrorCode.ResponseError]: true,\n    })\n  }\n}\n\nconst apiErrorCodes: { [C in APIErrorCode]: true } = {\n  [APIErrorCode.Unauthorized]: true,\n  [APIErrorCode.RestrictedResource]: true,\n  [APIErrorCode.ObjectNotFound]: true,\n  [APIErrorCode.RateLimited]: true,\n  [APIErrorCode.InvalidJSON]: true,\n  [APIErrorCode.InvalidRequestURL]: true,\n  [APIErrorCode.InvalidRequest]: true,\n  [APIErrorCode.ValidationError]: true,\n  [APIErrorCode.ConflictError]: true,\n  [APIErrorCode.InternalServerError]: true,\n  [APIErrorCode.ServiceUnavailable]: true,\n}\n\n/**\n * A response from the API indicating a problem.\n * Use the `code` property to handle various kinds of errors. All its possible values are in `APIErrorCode`.\n */\nexport class APIResponseError extends HTTPResponseError<APIErrorCode> {\n  readonly name = \"APIResponseError\"\n\n  static isAPIResponseError(error: unknown): error is APIResponseError {\n    return isNotionClientErrorWithCode(error, apiErrorCodes)\n  }\n}\n\nexport function buildRequestError(\n  response: SupportedResponse,\n  bodyText: string\n): APIResponseError | UnknownHTTPResponseError {\n  const apiErrorResponseBody = parseAPIErrorResponseBody(bodyText)\n  if (apiErrorResponseBody !== undefined) {\n    return new APIResponseError({\n      code: apiErrorResponseBody.code,\n      message: apiErrorResponseBody.message,\n      headers: response.headers,\n      status: response.status,\n      rawBodyText: bodyText,\n    })\n  }\n  return new UnknownHTTPResponseError({\n    message: undefined,\n    headers: response.headers,\n    status: response.status,\n    rawBodyText: bodyText,\n  })\n}\n\nfunction parseAPIErrorResponseBody(\n  body: string\n): { code: APIErrorCode; message: string } | undefined {\n  if (typeof body !== \"string\") {\n    return\n  }\n\n  let parsed: unknown\n  try {\n    parsed = JSON.parse(body)\n  } catch (parseError) {\n    return\n  }\n\n  if (\n    !isObject(parsed) ||\n    typeof parsed[\"message\"] !== \"string\" ||\n    !isAPIErrorCode(parsed[\"code\"])\n  ) {\n    return\n  }\n\n  return {\n    ...parsed,\n    code: parsed[\"code\"],\n    message: parsed[\"message\"],\n  }\n}\n\nfunction isAPIErrorCode(code: unknown): code is APIErrorCode {\n  return typeof code === \"string\" && code in apiErrorCodes\n}\n"]}