FE_Dev / hooks /use-delayed-error-display.ts
GitHub Actions
Deploy from GitHub Actions [dev] - 2025-10-31 07:28:50
68f7925
import { useEffect, useState } from 'react';
export interface UseDelayedErrorDisplayOptions {
error: Error | null;
isLoading: boolean;
delayMs?: number; // デフォルト90000ms (90秒)
}
export interface UseDelayedErrorDisplayResult {
shouldShowError: boolean;
shouldShowLoading: boolean;
delayedError: Error | null;
}
/**
* エラー発生後も指定時間(デフォルト90秒)はローディング表示を継続し、
* 時間経過後にエラーを表示するHook
*
* @param options エラー、ローディング状態、遅延時間(ミリ秒)
* @returns エラー表示すべきか、ローディング表示すべきか、遅延後のエラー
*/
export function useDelayedErrorDisplay({
error,
isLoading,
delayMs = 90000, // 90秒(本番設定)
}: UseDelayedErrorDisplayOptions): UseDelayedErrorDisplayResult {
const [errorTimestamp, setErrorTimestamp] = useState<number | null>(null);
const [shouldShowError, setShouldShowError] = useState(false);
// エラーが発生した時刻を記録
useEffect(() => {
if (error && !errorTimestamp) {
setErrorTimestamp(Date.now());
setShouldShowError(false);
} else if (!error) {
// エラーがクリアされた場合はリセット
setErrorTimestamp(null);
setShouldShowError(false);
}
}, [error, errorTimestamp]);
// 指定時間経過後にエラーを表示
useEffect(() => {
if (!errorTimestamp || !error || shouldShowError) {
// すでにエラー表示状態の場合は何もしない
return;
}
const checkElapsed = () => {
const elapsed = Date.now() - errorTimestamp;
if (elapsed >= delayMs) {
setShouldShowError(true);
}
};
// 初回チェック
checkElapsed();
// 1秒ごとにチェック
const interval = setInterval(checkElapsed, 1000);
return () => clearInterval(interval);
}, [errorTimestamp, error, delayMs, shouldShowError]);
// ローディング表示判定:
// - 通常ローディング中、または
// - エラーが発生しているが、まだ遅延時間内
const shouldShowLoading = isLoading || (error !== null && errorTimestamp !== null && !shouldShowError);
return {
shouldShowError,
shouldShowLoading,
delayedError: shouldShowError ? error : null,
};
}