File size: 2,777 Bytes
68f7925
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// カスタムエラークラス
export class AppError extends Error {
  constructor(
    message: string,
    public code: string,
    public statusCode?: number,
    public details?: unknown,
  ) {
    super(message);
    this.name = 'AppError';
  }
}

// URL入力関連のエラータイプ
export enum URLInputErrorType {
  INVALID_URL = 'INVALID_URL',
  SCREENSHOT_FAILED = 'SCREENSHOT_FAILED',
  NETWORK_ERROR = 'NETWORK_ERROR',
  TIMEOUT = 'TIMEOUT',
  UNSUPPORTED_SITE = 'UNSUPPORTED_SITE',
}

// エラーメッセージマッピング
export const errorMessages: Record<string, string> = {
  [URLInputErrorType.INVALID_URL]: '有効なURLを入力してください',
  [URLInputErrorType.SCREENSHOT_FAILED]:
    'スクリーンショットの取得に失敗しました',
  [URLInputErrorType.NETWORK_ERROR]: 'ネットワークエラーが発生しました',
  [URLInputErrorType.TIMEOUT]:
    'タイムアウトしました。しばらくしてから再度お試しください',
  [URLInputErrorType.UNSUPPORTED_SITE]: 'このサイトはサポートされていません',
  SYSTEM_ERROR: 'システムエラーが発生しました',
  UNKNOWN_ERROR: '予期しないエラーが発生しました',
};

// エラーメッセージを取得
export function getErrorMessage(error: unknown): string {
  if (error instanceof AppError) {
    return errorMessages[error.code] || error.message;
  }

  if (error instanceof Error) {
    // タイムアウトエラー
    if (error.message.includes('timeout')) {
      return errorMessages[URLInputErrorType.TIMEOUT];
    }
    // ネットワークエラー
    if (error.message.includes('fetch') || error.message.includes('network')) {
      return errorMessages[URLInputErrorType.NETWORK_ERROR];
    }
    return error.message;
  }

  return errorMessages.UNKNOWN_ERROR;
}

// エラーレスポンスの型
export interface ErrorResponse {
  error: {
    message: string;
    code: string;
    details?: unknown;
  };
}

// APIエラーをパース
export function parseApiError(response: unknown): AppError {
  if (
    response &&
    typeof response === 'object' &&
    'error' in response &&
    response.error &&
    typeof response.error === 'object'
  ) {
    const error = response.error as Record<string, unknown>;
    const statusCode =
      'statusCode' in response && typeof response.statusCode === 'number'
        ? response.statusCode
        : undefined;
    return new AppError(
      (typeof error.message === 'string' ? error.message : null) ||
        errorMessages.UNKNOWN_ERROR,
      (typeof error.code === 'string' ? error.code : null) || 'UNKNOWN_ERROR',
      statusCode,
      error.details,
    );
  }

  return new AppError(errorMessages.UNKNOWN_ERROR, 'UNKNOWN_ERROR', 500);
}