소스코드 참고 시 출처 표기 부탁드립니다!
에러의 종류
개발자와 유저의 에러 확인 방법
개발자
1.1 개발 중
1.2 배포 후
클라이언트 유저
컴포넌트에서 데이터 요청 함수를 실행할 경우
위 순으로 try문을 작성하고
에러가 발생할 경우 catch문에서 에러의 종류에 따라 핸들링함
catch문에서 error를 catch할 경우, 어떤 에러인지 확인하는 게 불가능하므로
커스텀 에러를 만들어 에러에 메세지와 함께 추가 정보 전달한다.https://javascript.info/custom-errors
Type Error
// TypeError.js : 에러의 타입을 나타냄
export default class TypeError extends Error {
constructor(message, type) {
super(message);
this.type = type;
}
}
// 사용 예시
// api 호출 함수
const getCard = () => throw new TypeError('500 status error', 'api')
// MyComponent.js
try{
const card = await getCard()
if(!card) throw new TypeError('card does not exist', 'data')
erturn card
}catch(e){
if(e.type==='api'){} // api 요청 에러 처리
else if(e.type==='data'){} // data 유효성 에러 처리
else{} // 코드 작성 에러 처리
}
ApiError
유저에게 상태 정보에 따라 서로 다른 페이지를 보여줄 경우,
catch하는 에러 메세지에서 status코드를 포함할 경우 쉽게 핸들링할 수 있다.
// ApiError.js 구현
import TypeError from './TypeError.js';
export default class ApiError extends TypeError {
constructor(message, type, status) {
super(message, type);
this.status = status;
}
}
// 사용 예시
const getCard = () => throw new ApiError('Internal Server error from getCard with status 500', 'api', 500)
// MyComponent.js
try{
const card = await getCard()
return card;
}catch(e){
if(e.type==='api'){
alertError(e.message, e.status)
}
//.. ..//
}
console.warn : 코드에 문제가 없는 loose한 에러
console.error : 반드시 수정해야될 에러
catch (e) {
let message;
if (e.type === 'api' || e.type === 'data') {
console.warn(e); // api, data validation에 의한 에러로, 사용자에게 보여줄 loose한 에러
message = e.message;
} else {
console.error(e); // 개발 시 처리해야될 치명적인 에러
message = `알 수 없는 에러가 발생했습니다. ${e.message}`;
// .. // 배포에서 의도치 않게 에러가 발생할 경우 개밡 팀으로 에러 피드백
}
// 에러 메세지 UI 띄우기
// 개발 시 에러 메세지는 페이지로 띄우고
// 유저 에러 메세지는 팝업형식이나 상태 코드별 페이지를 띄우면 좋을 듯
new ErrorMessage($catCard, message, e.status);
}
import ApiError from './utils/ApiError.js';
const API_ENDPOINT =
'<https://oivhcpn8r9.execute-api.ap-northeast-2.amazonaws.com/dev>';
const STATUS_ERROR_MESSAGE = // 클라이언트에 띄울 메세지
'서버가 원활하지 않습니다. 잠시 후 다시 시도해주세요';
const statusErrorMessages = [
false,
'Redirects Error',
'Client Error',
'Server Error',
];
// 개발 디버깅 시 사용할 에러 메세지 생성
const getStatusErrorMessage = (res, name) => {
const errorTypes = [300, 400, 500, 600];
for (let i = 0; i < errorTypes.length; i++) {
const errorType = errorTypes[i];
if (res.status < errorType) {
if (errorType === 300) return false;
return `API request error : ${statusErrorMessages[i]} with status code ${res.status} from ${name}`;
}
}
};
const fetchData = async (url, name) => {
try {
const res = await fetch(url);
const statusErrorMessage = getStatusErrorMessage(res, name);
if (statusErrorMessage) // 상태 에러일 경우 status code 포함해서 에러 throw하기
throw new ApiError(statusErrorMessage, 'status', res.status);
return res.json();
} catch (e) {
// 요청 상태 에러 처리
if (e.type === 'status') {
console.warn(e); // 개발 디버깅에 필요한 에러 로깅 => 컴포넌트 내에서는 UI에 집중하기 위해 api 호출 함수에서 warn 로그 처리
throw new ApiError(STATUS_ERROR_MESSAGE, 'api', e.status); // UI에서 사용할 에러 메세지, 상태 코드와 함께 throw
}
// 코드 에러 처리
throw new Error(e);
}
};
const api = {
getCats: (keyword) =>
fetchData(`${API_ENDPOINT}/api/cats/search?q=${keyword}`, 'get cats'),
getCatById: (id) =>
fetchData(`${API_ENDPOINT}/api/cats/${id}`, 'get catById'),
getRandomCats: () =>
fetchData(`${API_ENDPOINT}/api/cats/random50`, 'get randomCats'),
};
export default api;
api 호출 함수로부터 전달 받는 에러 형식
api 호출 함수에 의한 에러 대응 방법
이외의 추가적인 TypeError
컴포넌트 데이터 요청 함수 내에서 새로운 타입의 에러를 생성해야할 경우,
TypeError를 throw하기
/* SearchResult.js
SearchResult 컴포넌트의 getCatInfo 함수 요약
고양이 카드 element를 전달받고 고양이 정보를 요청한 후
정보가 있을 경우 CatInfo를 리턴하는 함수
*/
getCatInfo = async ($catCard) => {
try {
// api 요청 실패 시 ApiError 또는 Error를 catch하게 됨
const { data } = await api.getCatById($catCard.dataset.id);
// api 요청에 성공했으나 컴포넌트 렌더링에 사용할 데이터가 invalid할 경우
if (!Object.keys(data).length) {
throw new TypeError(
'선택하신 고양이 상세 정보를 불러올 수 없습니다.',
'data' // data type의 에러 throw
);
}
const { id, url, name, temperament, origin } = data;
return { id, url, name, temperament, origin };
} catch (e) {
let message;
// api 또는 data 타입의 에러일 경우
if (e.type === 'api' || e.type === 'data') {
console.warn(e); // UI 메세지 console.warn
message = e.message;
} else {
console.error(e); // 이외의 에러는 개발 시 처리해야될 에러
message = `알 수 없는 에러가 발생했습니다. ${e.message}`;
// .. // 배포에서 발생할 경우 개발 팀으로 피드백하기
}
// UI 메세지 띄우기
// type을 포함하는 loose한 에러는 토스트를 띄우고
// type을 포함하지 않는 strict한 에러는 전체화면을 띄워 개발에서 놓치지 않게끔 수정하기
new ErrorMessage($catCard, message, e.status);
}
};
주관적으로 구현한 내용이므로 틀린 내용이 포함되었을 가능성이 높습니다!