errors.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import type { ApplyPatchErrorCode, ApplyPatchErrorKind } from './types';
  2. const APPLY_PATCH_ERROR_PREFIX: Record<ApplyPatchErrorKind, string> = {
  3. blocked: 'apply_patch blocked',
  4. validation: 'apply_patch validation failed',
  5. verification: 'apply_patch verification failed',
  6. internal: 'apply_patch internal error',
  7. };
  8. export class ApplyPatchError extends Error {
  9. override readonly cause?: unknown;
  10. constructor(
  11. readonly kind: ApplyPatchErrorKind,
  12. readonly code: ApplyPatchErrorCode,
  13. message: string,
  14. options?: {
  15. cause?: unknown;
  16. },
  17. ) {
  18. super(`${APPLY_PATCH_ERROR_PREFIX[kind]}: ${message}`);
  19. this.name = 'ApplyPatchError';
  20. this.cause = options?.cause;
  21. }
  22. }
  23. export function getErrorMessage(error: unknown): string {
  24. return error instanceof Error ? error.message : String(error);
  25. }
  26. export function createApplyPatchBlockedError(
  27. message: string,
  28. cause?: unknown,
  29. ): ApplyPatchError {
  30. return new ApplyPatchError('blocked', 'outside_workspace', message, {
  31. cause,
  32. });
  33. }
  34. export function createApplyPatchValidationError(
  35. message: string,
  36. cause?: unknown,
  37. ): ApplyPatchError {
  38. return new ApplyPatchError('validation', 'malformed_patch', message, {
  39. cause,
  40. });
  41. }
  42. export function createApplyPatchVerificationError(
  43. message: string,
  44. cause?: unknown,
  45. ): ApplyPatchError {
  46. return new ApplyPatchError('verification', 'verification_failed', message, {
  47. cause,
  48. });
  49. }
  50. export function createApplyPatchInternalError(
  51. message: string,
  52. cause?: unknown,
  53. ): ApplyPatchError {
  54. return new ApplyPatchError('internal', 'internal_unexpected', message, {
  55. cause,
  56. });
  57. }
  58. export function isApplyPatchError(error: unknown): error is ApplyPatchError {
  59. return error instanceof ApplyPatchError;
  60. }
  61. export function isApplyPatchBlockedError(error: unknown): boolean {
  62. return isApplyPatchError(error) && error.kind === 'blocked';
  63. }
  64. export function isApplyPatchValidationError(error: unknown): boolean {
  65. return isApplyPatchError(error) && error.kind === 'validation';
  66. }
  67. export function isApplyPatchVerificationError(error: unknown): boolean {
  68. return isApplyPatchError(error) && error.kind === 'verification';
  69. }
  70. export function isApplyPatchInternalError(error: unknown): boolean {
  71. return isApplyPatchError(error) && error.kind === 'internal';
  72. }
  73. export function getApplyPatchErrorDetails(error: unknown):
  74. | {
  75. kind: ApplyPatchErrorKind;
  76. code: ApplyPatchErrorCode;
  77. message: string;
  78. }
  79. | undefined {
  80. if (!isApplyPatchError(error)) {
  81. return undefined;
  82. }
  83. return {
  84. kind: error.kind,
  85. code: error.code,
  86. message: error.message,
  87. };
  88. }
  89. export function ensureApplyPatchError(
  90. error: unknown,
  91. context: string,
  92. ): ApplyPatchError {
  93. if (isApplyPatchError(error)) {
  94. return error;
  95. }
  96. return createApplyPatchInternalError(
  97. `${context}: ${getErrorMessage(error)}`,
  98. error,
  99. );
  100. }