문제와 원인
관리자 대시보드나 회원·제보·이론 목록의 초기 조회가 실패하면 LoadingBlock이 공통 ErrorState로 교체된다. 현재 오류 컨테이너에는 role·aria-live와 초점 이동 처리가 빠져 있어, 비동기 실패를 보조기술에 전달할 의미가 누락된 상태다.
현재 코드
ErrorState
좌우로 이동해 전체 내용을 확인하세요. 키보드: ←·→, Home·End
export function ErrorState({ message, onRetry }: {
message: string;
onRetry: () => void;
}) {
return (
<div className="admin-empty error">
<span aria-hidden="true">!</span>
<strong>데이터를 불러오지 못했습니다.</strong>
<p>{message}</p>
<button className="admin-button" type="button" onClick={onRetry}>
다시 시도
</button>
</div>
);
}
로딩 컨테이너의 role="status"는 오류 컨테이너로 이어지지 않는다. aria-hidden="true"는 아이콘을 숨기며, 재시도 버튼은 onRetry를 호출한다.
진단 결과
과거·현재 원본 ErrorState·LoadingBlock을 macOS Node.js·React에서 실행해 서버 오류·네트워크 오류·재시도 실패 합성 메시지 3개를 버전별 각 1회 렌더링하고 콜백을 입력별 1회 호출했다. 같은 원본을 로컬 React 화면 1280×720 CSS px·DPR 2에서 실행해 HTTP 500·응답 소켓 종료·재시도도 500인 조건을 버전별 각 1회 요청하고, 조건마다 재시도 버튼을 1회 클릭했다.
좌우로 이동해 전체 내용을 확인하세요. 키보드: ←·→, Home·End
| 정적 렌더 검사 | 과거 코드 | 현재 코드 |
|---|---|---|
오류 컨테이너의 role 누락 | 3/3개 | 3/3개 |
오류 컨테이너의 aria-live 누락 | 3/3개 | 3/3개 |
| 재시도 버튼 출력 | 3/3개 | 3/3개 |
| 재시도 콜백 1회 호출 | 3/3개 | 3/3개 |
LoadingBlock 역할 | status | status |
좌우로 이동해 전체 내용을 확인하세요. 키보드: ←·→, Home·End
| 브라우저 요청·DOM 결과 | 과거 코드 | 현재 코드 |
|---|---|---|
초기 오류의 role·aria-live | 각각 3/3조건에서 누락 | 각각 3/3조건에서 누락 |
| 재시도 버튼 / 클릭 뒤 콜백 | 3/3조건에서 1개 / 1회 | 3/3조건에서 1개 / 1회 |
| 500·네트워크 실패 뒤 정상 재시도 | 2/2조건 성공 | 2/2조건 성공 |
| 재시도도 500인 조건 | 1/1조건 오류 유지 | 1/1조건 오류 유지 |
서버가 HTTP 500을 반환하면 오류 문구와 다시 시도 버튼이 표시됐다.
다시 시도한 요청이 성공하면 정상 조회 화면으로 전환됐다.
응답 소켓이 종료되면 네트워크 오류가 표시됐다.
재시도 요청도 실패하면 오류 상태와 실패 문구를 유지했다.