コンテンツにスキップ

エラーハンドリング

概要

@authrim/web のすべての非同期メソッドは AuthResponse<T> を返します — エラー処理を型安全で一貫したものにする判別共用体です:

type AuthResponse<T> =
| { data: T; error: null }
| { data: null; error: AuthError };

SDKメソッドにtry/catchは不要です。まず error を確認してから data を使用します:

const { data, error } = await auth.passkey.login();
if (error) {
// エラー処理
console.error(error.message);
return;
}
// TypeScriptはここで data が non-null であると認識します
console.log(data.user);

AuthError構造

interface AuthError {
/** Authrimエラーコード(例:'AR003002') */
code: string;
/** OAuth 2.0エラーコード(例:'user_cancelled') */
error: string;
/** 人間が読めるエラーメッセージ */
message: string;
/** 操作をリトライ可能か */
retryable: boolean;
/** エラーの重大度 */
severity: 'info' | 'warn' | 'error' | 'critical';
}

エラーコード形式

エラーコードは AR{ドメイン}{番号} のパターンに従います:

プレフィックスドメイン
AR001セッション / 認証セッションエラー
AR002Email Code送信/検証エラー
AR003Passkey(WebAuthn)セレモニーエラー
AR004ソーシャルログインプロバイダー/コールバックエラー
AR005OAuth / OIDCトークン/コールバックエラー

重大度レベル

レベル意味一般的なアクション
info想定内の状態(例:未認証)通常通りUIを更新
warn回復可能な問題(例:サイレント認証失敗)ログして続行
error失敗した操作(例:無効なコード)エラーメッセージを表示
critical予期しない障害(例:サーバーエラー)エラー表示+リトライを提案

リトライ可能フラグ

if (error.retryable) {
showMessage('問題が発生しました。もう一度お試しください。');
// リトライボタンを提供
} else {
showMessage(error.message);
// リトライを提供しない — ユーザーのアクションが必要
}

エラーハンドリングパターン

基本パターン

const { data, error } = await auth.passkey.login();
if (error) {
showErrorMessage(error.message);
return;
}
// 成功
redirect('/dashboard');

エラーコードによる分岐

const { data, error } = await auth.emailCode.verify(email, code);
if (error) {
switch (error.code) {
case 'AR002003':
// コード期限切れ — 再送信
await auth.emailCode.send(email);
showMessage('コードの有効期限が切れました。新しいコードを送信しました。');
break;
case 'AR002004':
// コード間違い
showMessage('コードが間違っています。もう一度お試しください。');
break;
case 'AR002005':
// 試行回数超過
showMessage('試行回数が多すぎます。しばらくお待ちください。');
break;
default:
showMessage(error.message);
}
return;
}

重大度ベースの処理

function handleAuthError(error: AuthError) {
switch (error.severity) {
case 'info':
// 本当のエラーではない — 想定内の状態
console.log(error.message);
break;
case 'warn':
// 回復可能 — ログするがアラートしない
console.warn(`[${error.code}] ${error.message}`);
break;
case 'error':
// ユーザーに表示
showToast(error.message, 'error');
break;
case 'critical':
// 目立つように表示+デバッグ用にログ
showAlert(error.message);
logToService(error);
break;
}
}

リトライパターン

async function loginWithRetry(maxRetries = 2) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const { data, error } = await auth.passkey.login();
if (!error) {
return data;
}
if (!error.retryable || attempt === maxRetries) {
showMessage(error.message);
return null;
}
// リトライ前に短い遅延
await new Promise(resolve => setTimeout(resolve, 1000));
}
return null;
}

エラーコードリファレンス

Passkey(AR003xxx)

コードエラーリトライ可説明
AR003000passkey_error場合による一般的なPasskeyエラー
AR003001webauthn_not_supported不可ブラウザがWebAuthn非対応
AR003002user_cancelledユーザーがセレモニーをキャンセル
AR003003credential_not_found不可一致するクレデンシャルなし
AR003004authenticator_error認証器デバイスエラー
AR003005server_validation_failedサーバーがクレデンシャルを拒否

Email Code(AR002xxx)

コードエラーリトライ可説明
AR002000email_code_error場合による一般的なEmail Codeエラー
AR002001invalid_email不可無効なメール形式
AR002002rate_limited不可送信リクエスト過多
AR002003code_expired不可検証コード期限切れ
AR002004invalid_code間違ったコード
AR002005max_attempts不可検証失敗回数超過

ソーシャルログイン(AR004xxx)

コードエラーリトライ可説明
AR004001provider_not_configured不可プロバイダー未設定
AR004002popup_blocked不可ブラウザがポップアップをブロック
AR004003user_deniedユーザーが同意を拒否
AR004004provider_errorプロバイダーがエラーを返した
AR004005callback_failed不可コールバック検証失敗

OAuth(AR005xxx)

コードエラーリトライ可説明
AR005001oauth_callback_error不可コールバック処理失敗
AR005002silent_auth_failed不可サイレント認証失敗
AR005003no_tokens不可トークン未受信
AR005004popup_login_errorポップアップログイン失敗

一元化されたエラーハンドラー

アプリケーション全体で再利用可能なエラーハンドラーを作成:

function handleError(error: AuthError, context: string) {
// すべてのエラーをログ
console.error(`[${context}] ${error.code}: ${error.message}`);
// ユーザー向けメッセージ
if (error.severity === 'critical') {
showAlert('予期しないエラーが発生しました。しばらくしてから再試行してください。');
} else if (error.severity === 'error') {
showToast(error.message);
}
// アナリティクス
trackError({ code: error.code, context, severity: error.severity });
}
// 使用方法
const { data, error } = await auth.passkey.login();
if (error) {
handleError(error, 'passkey-login');
return;
}

次のステップ