중요: @boundary는 개발자 프리뷰 기능입니다.
Angular 템플릿은 렌더링과 변경 감지 중 발생하는 런타임 오류를 적절하게 처리할 수 있는 오류 경계를 지원합니다.
오류 경계는 한 컴포넌트의 실패로 애플리케이션 전체가 중단되는 것을 방지하고, 사용자에게 대체 UI를 표시할 수 있게 합니다.
@boundary와 @error로 오류 처리하기
@boundary 블록은 템플릿의 일부를 감쌉니다.
경계 안에 있는 컴포넌트나 디렉티브에서 초기화 또는 변경 감지 중 오류가 발생하면, 프레임워크가 오류를 처리하고 대신 @error 블록을 렌더링합니다.
@boundary {
<app-risky-component />
} @error {
<p>문제가 발생했습니다!</p>
}
오류 객체에 접근하기
암묵적으로 제공되는 $error 변수를 사용하면 발생한 오류에 접근할 수 있습니다.
@boundary {
<app-risky-component />
} @error {
<p>에러가 발생했습니다: {{ $error.message }}</p>
}
경계 초기화하기
@error 블록에서 암묵적으로 제공되는 $reset 함수를 호출하면 @boundary의 콘텐츠를 다시 렌더링할 수 있습니다.
이 함수를 호출하면 경계 상태를 초기화하고 원래 콘텐츠를 다시 렌더링합니다.
@boundary {
<app-flaky-component />
} @error {
<p>로딩에 실패했습니다.</p>
<button (click)="$reset()">다시 시도</button>
}
when으로 조건에 따라 오류 처리하기
when 절을 사용하면 특정 종류의 오류를 조건에 따라 처리해서 서로 다른 대체 UI를 제공할 수 있습니다.
Angular는 오류를 처리할 때 이 조건을 평가합니다.
@boundary {
<app-chart-dashboard />
} @error (let err; reset = $reset; when isRenderError(err)) {
<p>네트워크에 문제가 있습니다. 연결을 확인하세요.</p>
<button (click)="reset()">재시도</button>
} @error {
<p>예상하지 못한 에러가 발생했습니다: {{ $error.message }}</p>
}
@error 블록은 가장 구체적인 조건부터 일반적인 조건 순서로 배치하세요.
Angular는 when 절을 순서대로 평가하고 처음으로 참이 되는 블록을 사용합니다.
마지막에 when 절이 없는 @error 블록을 두면 나머지 모든 오류를 처리할 수 있습니다.
전역 오류 핸들러와 통합하기
경계가 오류를 처리하더라도 Angular는 전역 ErrorHandler에 오류를 알릴 수 있습니다.
커스텀 ErrorHandler에 선택적인 onViewError 훅을 구현하면 경계에서 처리한 오류를 오류 추적 서비스에 기록할 수 있습니다.
@Injectable()
export class MyErrorHandler implements ErrorHandler {
handleError(error: any): void {
// 처리되지 않은 에러를 처리합니다.
}
onViewError(error: Error, details: ErrorDetails): void {
// @boundary가 처리한 에러를 처리합니다.
console.warn('Caught by boundary:', details.boundary);
myErrorTrackingService.log(error);
}
}
중요: @error 블록 자체에서 오류가 발생하면 바로 바깥쪽 @boundary로 전파되며, 바깥 경계가 없으면 Angular가 처리되지 않은 애플리케이션 오류로 취급합니다.
콘텐츠 프로젝션
컴포넌트에서 콘텐츠 프로젝션을 사용한다면, <ng-content>를 @boundary로 감싸도 프로젝션된 콘텐츠의 오류는 처리하지 못합니다.
해당 콘텐츠는 받는 컴포넌트의 뷰가 아니라, 콘텐츠를 선언한 뷰에 속하기 때문입니다.
예를 들어 다음 템플릿을 사용하는 래퍼 컴포넌트는 안으로 프로젝션된 컴포넌트에서 발생하는 오류를 처리하지 못합니다.
@boundary {
<ng-content />
} @error {
<p>문제가 발생했습니다!</p>
}
이러한 오류를 처리하려면 부모 템플릿에서 래퍼 컴포넌트와 프로젝션할 콘텐츠를 함께 @boundary로 감싸세요.
@boundary {
<app-wrapper>
<app-risky-component />
</app-wrapper>
} @error {
<p>문제가 발생했습니다!</p>
}
동적 뷰와 프로그래밍 방식의 오류 처리
오류 처리는 템플릿 문법에만 한정되지 않습니다.
컴포넌트나 내장 뷰를 동적으로 생성한다면 onError 옵션으로 오류를 처리할 수 있습니다.
자세한 내용은 프로그래밍 방식 렌더링 가이드의 렌더링 오류 처리하기를 참고하세요.