Angular에서 오류 포착 및 처리
18574 단어 angulartypescriptprogrammingtutorial
곤충의 일생
오류는 일반적으로 우리의 잘못이거나 다른 사람의 잘못입니다. 오늘 저는 후자에 관심이 있습니다. 타사 라이브러리 오류 및 API 관련 오류입니다. 비즈니스 계층에서 시작됩니다.
RxJS
연산자 또는 try ... catch
문을 통해 포착합니다. 비즈니스는 오류를 처리할 책임이 없으므로 오류를 수정한 후 다시 반환해야 합니다.소비자 구성요소(UI 레이어)에서 오류를 포착하고 처리할 수 있습니다. 반응은 토스트 메시지, 리디렉션, 오류 스크롤, 대화 등이 될 수 있습니다. 항상 "조용히 처리"할 수 있습니다😏. 그렇게 하지 않으면 애플리케이션의 핵심에 있는 Angular Error Handler가 이를 로깅하고 아마도 추적기에 알려서 최종적으로 처리해야 합니다.
UI 대 백엔드 오류 메시지
API 서비스는 일반적으로 빌드 방법에 대한 전역적 이해가 있더라도 오류를 반환하는 고유한 방법이 있습니다. 백엔드에서 반환된 오류는 상황에 맞지 않으며 데이터베이스 개발자가 얼마나 자부심을 가지고 있는지에 관계없이 사용자에게 친숙하지 않습니다. 그들은 단순히 충분하지 않습니다. 다음 주에 토스트 메시지에 대해 이야기할 때 이를 증명할 예를 들겠습니다.
다행히 최근에는 서버 오류가 '코드'와 함께 반환되는 경우가 더 자주 발생합니다. UI에서 해당 코드를 사용하여 해당 오류 메시지를 다시 만들 수 있습니다.
먼저 거꾸로 작업하면 다음은 간단한 오류 메시지(요청된 API 포인트의)를 반환하는 호출을 수행하는 구성 요소의 예입니다.
create(project: Partial<IProject>) {
// handling errors in a better way
this.projectService.CreateProject(project).subscribe({
next: (data) => {
console.log(data?.id);
},
error: (error) => {
// do something with error, toast, dialog, or sometimes, silence is gold
console.log(error);
}
});
}
// in a simpler non-subscribing observable
getProjects() {
this.projects$ = this.projectService.GetProjects().pipe(
catchError(error => {
// do something with error
console.log(error);
// then continue, nullifying
return of(null);
})
)
}
RxJS 사용자 정의 연산자: 다시 던지기
이것은 있는 그대로 충분히 강력하지 않습니다. 포착된 오류가 반드시 예상대로 표시되는 것은 아닙니다. 대신, 우리는 debug operator 에 대해 했던 것처럼
catchError
에 대해서만 observable*에 대한 사용자 지정 연산자를 만들 것입니다. 이렇게 하면 사이트별로 예상되는 오류의 모양이 준비됩니다.// custom RxJS operator
export const catchAppError = (message: string): MonoTypeOperatorFunction<any> => {
return pipe(
catchError(error => {
// prepare error here, then rethrow, so that subscriber decides what to do with it
const e = ErrorModelMap(error);
return throwError(() => e);
})
);
};
이 연산자는 모든 응답 오류를 포착하기 위해 Http 인터셉터에서 연결될 수 있습니다.
// in our http interceptor
return next
.handle(adjustedReq)
.pipe(
// debug will take care of logging
debug(`${req.method} ${req.urlWithParams}`, 'p'),
// catch, will prepare the shape of error
catchAppError(`${req.method} ${req.urlWithParams}`)
)
오류 모델: 교정
UI의 오류 모델에는 최소한 다음이 포함될 수 있습니다.
// in error.model
export interface IUiError {
code: string;
message?: string;
status?: number;
}
catchError
연산자에서 해당 오류를 반환해야 하며 보내기 전에 매핑해야 합니다. 이를 위해서는 일반적으로 반사회적 API 개발자와 이야기해야 합니다. 형식은 개발자가 결정하기 때문입니다.다음과 같이 서버 오류가 발생한다고 가정합니다(웹에서 매우 일반적임).
{
"error": [
{
"message": "Database failure cyclic gibberish line 34-44 file.py",
"code": "PROJECT_ADD_FAILED"
}
]
}
UiError
매퍼는 다음과 같습니다. 카니발에 대비하세요.// add this the error.model file
export const UiError = (error: any): IUiError => {
let e: IUiError = {
code: 'Unknown',
message: error,
status: 0,
};
if (error instanceof HttpErrorResponse) {
// map general error
e.message = error.message || '';
e.status = error.status || 0;
// dig out the message if found
if (error.error?.errors?.length) {
// accumulate all errors
const errors = error.error.errors;
e.message = errors.map((l: any) => l.message).join('. ');
// code of first error is enough for ui
e.code = errors[0].code || 'Unknown';
}
}
return e;
};
RxJS
운영자는 이제 이 매퍼를 사용할 수 있습니다.// custom operator
export const catchAppError = (message: string): MonoTypeOperatorFunction<any> => {
return pipe(
catchError(error => {
// map first
const e = UiError(error);
// then rethrow
return throwError(() => e);
})
);
};
Unfortunately, you will not find two public APIs that return the same error format. Thus, you need to create a manual mapper for every specific type, individually. Will not go into details about this.
디버그 맞춤 연산자를 만들려는 이전 시도에서도 오류를 로그아웃했습니다. 하지만 이제 새 연산자가 있으므로 디버그 연산자에서 로거를 제거하고 새 연산자에 배치하여 예상한 대로 정확하게 오류를 기록해야 합니다.
// update debug operator, remove error handling
export const debug = (message: string, type?: string): MonoTypeOperatorFunction<any> => {
return pipe(
tap({
next: nextValue => {
// ...
},
// remove this part
// error: (error) => {
// ...
// }
})
);
};
// custom operator, add debugging
export const catchAppError = (message: string): MonoTypeOperatorFunction<any> => {
return pipe(
catchError((error) => {
// map out to our model
const e = UiError(error);
// log
_debug(e, message, 'e');
// throw back to allow UI to handle it
return throwError(() => e);
})
);
};
부품 처리
지금까지 우리가 한 일은 서버에서 오류를 그대로 통과시키는 것뿐이었습니다. 이러한 오류를 처리하는 가장 일반적인 방법은 토스트 메시지입니다. 그러나 건배는 서사시입니다. 다음 주에 토스트에 대해 이야기하겠습니다. 😴
여기까지 읽어주셔서 감사합니다. 불이 났다면 알려주세요.
프로젝트가 진행 중입니다StackBlitz.
자원
관련 게시물
Reference
이 문제에 관하여(Angular에서 오류 포착 및 처리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ayyash/catching-and-handling-errors-in-angular-2c4j텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)