2023. 10. 17. 19:11ㆍb:develop
프론트엔드로 전향 후
기존 UI 리뉴얼 및 개선 이라는 담당 업무가 생겼다.
약 세달의 시간 동안 이쁘지도 않은 회색 화면을 깔끔하고 이쁘게 변경하였다.
"나비효과" 의 시작
영화제목인줄 알았지만
나의 작은(?) 세달의 코딩이 예상치 못한 엄청난 결과를 불러일으킨
최근이었다.
[우당탕탕]
이슈1. 기능과 상관없이 화면에서 무한대로 polling 되는 API 호출을 막았더니 검색이 안된다
이슈2. 컴포넌트의 통합이라는 명목하에 버튼의 위치를 통일 시켰더니 active panel / 잘되던 Save기능 등이 안된다
이슈3. 기존에 되던 기능이 안된다
[원인분석]
문제1. 앵귤러를 사용하면서도 의존성을 파악하지 않고 컴포넌트를 살피지 않았다
문제2. 버튼이 이쁘지 않아 왜 그렇게 만들었는지 이해하지 않았다
문제3. 아직도 부족하다
-
이렇게 발견한 이슈를 jira에 리스트업해가면서 고치고 있다.
충분히 막을 수 있었던 문제들이 반복적으로 일어나 다시 기초부터, 구조부터 알아야겠다는 생각이 든다.
에러를 처리하려면 누구보다 에러를 잘 아는 개발자가 되어야겠단 생각에
에러 처리에 관해 학습하면 좋을 거 같단 생각에 자료를 만들었다.
[ 한눈에 보이는 에러 처리 ]
에러는 어디서부터 시작되는 걸까?
나의 부족함이 9할이겠지만 가끔 예상치 못한 이슈들이 터져 나온다.
스스로 많은 이슈를 불러일으키고 에러에 대한 지식이 부족하니 외부에서 발생한 에러인지 판단 못한 적도 있었다. (부끄 ._.)
이런 경험을 바탕으로 한번 자세히 알아보고자 조사했다.
1. 내부로부터 시작되는 에러: 외부 영향과 관계없이 개발자가 작업한 코드에서 발생한 에러
- 개발자의 실수 (대문자 소문자 실수, 타입 실수 등)
-> Syntax Error / Logical Error / Runtime Error - 기획을 잘못 이해함
- 커뮤니케이션 오류
- 특수한 상황에 대한 처리가 미흡함
-> 최신 브라우저에서 기능이 바뀜, Safari 특정 버전의 Indexed DB API 버그, 특이 케이스에서만 발생하는 런타임 오류 등
2. 외부로부터 시작되는 에러: 외부 영향 때문에 발생하는 에러
- 인터넷 상태가 좋지 않음
- 디바이스 상태 오류 (베터리, 메모리 등)
- 사용자의 잘못된 입력 (ex. URL 입력오류)
- 서버로부터 발생한 에러 (4xx에러, 5xx에러)
에러 핸들링
어떻게 에러가 어떻게 발생하는지 알게 되었지만, 사실 실무에서 100퍼센트 응대하기란 어렵다.
좀 더 유연한 처리 방법이 필요하다.
특히 UI를 개발하는 개발자로서
1. 사용자에게 에러에 대해 인지시키고 다른 행동을 할 수 있도록 유도하여 서비스에 대한 부정적인 경험 방지
2. 데이터베이스에 정보를 넣는 작업일 경우 서비스의 트랜잭션에 영향을줘 서비스 장애를 일으키는 현상 발생 방지
를 해야 한다고 생각한다.
그래서 필요한 게 바로 '에러핸들링' 이다.
에러 핸들링이란?
- 코드 실행 -> 에러 발생 -> 예외처리 -> 실행 흐름 복구
코드가 실행되고 예상하거나 예상치 못했던 상황에서 에러가 발생했을 때 자바스크립트에서 지원하는 기본적인
기능들로 예외 처리를 하여 애플리케이션이 중단되는 것을 막고 실행 흐름이 이어 갈 수 있도록 복구 하는 것
(오류가 발생할 수도 있고 아닐 수도 있는 것을 '예외'구문으로 처리)
에러 정리
현실적으로 모든 에러를 처리하고 끊기에는 어렵지만 그렇다고 손 놓고 있을 수도 없는 일!
1. 에러가 발생한 곳에서 처리 (에러전파를 최대한 막기)
// 에러가 최초 발생한 함수 - API호출 (Service)
// console.error() 정도의 역할 후 에러 2번으로 전달
fetchData() {
return this.http.get('/api/data').pipe(
catchError(error => {
console.error('API Error:', error);
return throwError(error);
})
);
}
// 1번 함수의 반환값을 표현하는 컴포넌트
// 이 컴포넌트는 서비스의 결과를 받아 화면에 표시
// 만약 에러가 발생하면, 에러를 처리하거나 에러 핸들러에 전달
@Component ({
selector: 'app-data',
template: `<div *ngIf="error">{{ error }}</div><div *ngIf="data">{{ data }}</div>`
})
…
ngOnInit() {
this.dataService.fetchData().subscribe(
response => {
this.data = response;
// observable 성공. this.data에 fetchData데이터 있음
}, error => {
this.error = `Failed to fetch data: ${error.message}`;
// 여기서 에러를 다루거나, 다음 단계인 에러 핸들러로 전달
}
);
}
// 에러 핸들러는 전체 애플리케이션의 에러를 관리하며, 미처 처리되지 않은 에러를 캐치하고 처리
import { ErrorHandler, Injectable } from '@angular/core';
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
handleError(error: any): void {
// 모든 에러가 여기로 도착합니다. 원하는 로직을 추가하여 에러를 처리
console.error('Global error handler caught:', error);
}}
// AppModule에서 사용하려면 다음과 같이 추가해야 합니다.
// providers: [{ provide: ErrorHandler, useClass: GlobalErrorHandler }]
2. 에러를 정리 후 다음 레이어에서 처리
- 서비스 발생한 에러 컴포넌트에 내려줘서 컴포넌트서 처리
- 에러를 정리해서 보기 쉽거나 처리하기 쉽게 다른 에러로 치환해서 전달
- 빈 화면 alert등
** 서버로부터 온 401 에러를 UI 에서 필요한 정보만 추출해서 UI 쪽에 전달
- 로그인 하도록 유도 -> 로그인 화면 보여주거나 로그인 필요하다는 메시지 UI 노출
3. 비동기 API통신에서의 에러 핸들링
- API를 통해 통신할 때 상태 코드를 통해서 예외 상황 구분 (하나의 상태 코드에 다양한 상황이 있을 수 있음)
- API 응답에 관해 에러코드, 메시지를 활용하여 사용자에게 가이드 또는 안내를 줄 수 있음
- 빈 화면 alert등
** 잘못된 페이지나 없는 페이지 접근
- 리다이렉트로 다른 페이지 이동
- 사용자에게 접근할 수 없다는 의미 전달
보너스 체크포인트
자바스크립트와 타입스크립트를 쓰고 있는 지금 체크해보면 좋을 포인트 같아 메모
JS/TS 컴파일 환경 에러
1. 내부로부터 시작되는 에러
- 컴파일 오류 : 문법을 잘못 작성하는 듯 코드가 컴파일 될 때 컴파일러가 해석하지 못해서 발생
- 런타임 오류 : 프로그램이 동작할 때 발견할 수 있는 에러 쉽게 try catch 에서 잡히는 에러
** 자바스크립트에서는 런타임 에러를 예외라고 부릅니다.
- 자바스크립트 언어는 동적 프로그래밍 언어이기 때문에 프로그램이 동작할 때(런타임)
실시간으로 Type이 결정되어서 모든 에러가 컴파일 단계가 아닌 런타임 환경에서 발생 - 최악의 경우 사용자가 어플리케이션을 사용할 때 에러가 발생
- 따라서 컴파일 환경에서 타입에 관련된 에러를 잡을 수 있도록 도와주는 정적타입 언어인 TypeScript 사용
- 타입스크립트만 쓰면 문제가 없어 라기보단 타입스크립트를 잘 활용하면 런타임 전에 오류 발견 가능
2. 런타임 에러 핸들링
// 에러 처리 코드를 미리 등록해 두고 에러가 발생하면 에러 처리 코드로 점프하도록 하는 방법
try {
console.log (‘try’) // 실행할 코드(에러가 발생할 가능성이 있는 코드)
} catch(err) {
// try 코드 블록에서 에러가 발생하면 이 코드 블록의 코드가 실행된다.
console.error (‘error’) // err에는 try 코드 블록에서 발생한 Error 객체가 전달된다.
} finally {
console.log (‘finally’) // 에러 발생과 상관없이 반드시 한 번 실행된다.
}
try...catch...finally 조심하기
catch에 넘겨지는 error 객체의 타입을 보장할 수 없고, 오류를 해결하는 것이 아닌 숨기는 것이라
코드의 가독성이 떨어지고 유지보수가 어렵다. 의미 있는 결과를 내보낼 수 없다면, 에러를 터트려
추후에 모니터링 하는 것이 더 좋을 수도 있다.
'b:develop' 카테고리의 다른 글
[js] hasOwnProperty vs in 차이 (0) | 2024.04.24 |
---|---|
[UI개발/HTML/CSS] input type file UI 버튼 커스터마이징 (input type="file" 스타일 css변경) (0) | 2023.09.04 |
[mac M1] M1 맥북 에어 homebrew로 nvm 설치 (노드버전관리) (0) | 2023.08.15 |
Angular CLI Setting (앵귤러 설치 및 환경설정) (0) | 2023.08.14 |