(() => {
// 오류 핸들링
const handler = {
authCodes: ['CECO003', 'CECO005', 'CECO007', 'O0020', 'CECA003', 'CEDI001', 'PPVE0004'],
orderAuthCodes: ['O3336', 'O3338'],
adultCodes: ['CEPR006'],
adultConfirmCodes: ['O0037'],
homeCodes: ['CEST008', 'CEST006', 'CEST007', 'B0018'],
mallExpiredCodes: ['M0009'],
replacePageRequiredHandlerKey: ['AUTH', 'AUTH_AGE'],
redirectUrl: {
HOME: '/',
AUTH: '/pages/sign-in/sign-in.html',
AUTH_AGE: '/pages/intro/adult-certification.html',
EXPIRED_MALL: '/pages/error/expired-mall.html',
SERVICE_CHECK: '/pages/error/service-check.html',
ORDER_AUTH: '/pages/sign-in/member-authentication.html',
},
isUnauthorized: (error) => handler.authCodes.includes(error.code) || error.status === 401,
getServiceErrorKey: ({ status, error }) => {
if (!error?.code) return null;
if (status === 402 || handler.mallExpiredCodes.includes(error.code)) return 'EXPIRED_MALL';
if (status === 503) return 'SERVICE_CHECK';
return null;
},
getHandlerKey: ({ error, payload }) => {
if (!error?.code) return null;
if (handler.isUnauthorized(error)) return 'AUTH';
if (handler.orderAuthCodes.includes(error.code)) {
ShopbySkin.utils.setLocalStorage('REGISTER_ORDER_AFTER_AUTHENTICATION', JSON.stringify(payload));
return 'ORDER_AUTH';
}
if (handler.adultCodes.includes(error.code)) return 'AUTH_AGE';
if (handler.homeCodes.includes(error.code)) return 'HOME';
return null;
},
getHandlerConfirmKey: (error) => {
if (!error?.code) return null;
if (handler.adultConfirmCodes.includes(error.code))
return {
message: '해당 상품은 성인전용 상품입니다.
성인인증 후 상품을 구매하시겠습니까?',
onConfirm: () => {
handler.redirect('AUTH_AGE');
},
};
return null;
},
getHandlerMyPayAuthErrorKey: (error) => {
if (!error.code) return null;
const message = error?.error?.description || error?.message || error?.description;
if (handler.isUnauthorized(error)) return { nextPath: 'AUTH', message };
return null;
},
// eslint-disable-next-line complexity
getHandlerAppCardAuthErrorKey: (error) => {
const errorCode = error?.error?.code ?? error.code;
if (!errorCode) return null;
if (errorCode === 'ACEC0001') {
return { message: '앱카드 결제가 불가합니다. 다른 결제수단으로 다시 시도해 주세요.' };
}
if (errorCode === 'PROVIDER_SERVER_ERROR') {
const searchParams = new URLSearchParams(location.search);
const fromUrl = searchParams.get('from') ?? '/';
return { nextPath: fromUrl, message: '앱카드 인증에 실패하였습니다. 다시 시도해 주세요.' };
}
return null;
},
redirect: (handlerKey) => {
const url = `${handler.redirectUrl[handlerKey]}?from=${encodeURIComponent(location.href)}`;
if (handler.replacePageRequiredHandlerKey.includes(handlerKey)) {
location.replace(url);
} else {
location.href = url;
}
},
getRedirectUrl: (handlerKey) => {
const redirectUrl =
handler.redirectUrl[handlerKey] !== location.pathname
? `${handler.redirectUrl[handlerKey]}?from=${encodeURIComponent(location.href)}`
: '';
return redirectUrl;
},
};
const locationHandler = {
map: {
'/display/events': {
next: -1,
},
'/claims': {
next: -1,
exceptCodes: ['CL0058'],
},
'/product-detail': {
next: '/',
},
'/products': {
next: '/',
},
'/display/sections': {
next: '/',
checkReplacementStatus: (reason) => {
if (reason?.error?.serverError?.status === 404) {
return true;
}
if (reason?.error?.code === 'PSEC0002') {
return true;
}
return false;
},
},
'/boards/posts': {
next: '/',
},
},
getLocationInfo: (reason) => {
const locationMap = locationHandler.map;
const { path } = reason.error?.serverError ?? {};
return locationMap[Object.keys(locationMap).find((key) => path?.includes(key))] ?? {};
},
isExceptError: (reason) => {
const { code } = reason.error?.serverError ?? {};
const { exceptCodes } = locationHandler.getLocationInfo(reason);
return exceptCodes?.includes?.(code);
},
getNextPath: (reason) => {
const { next } = locationHandler.getLocationInfo(reason);
return next ?? null;
},
getReplacementStatus: (reason) => {
const { checkReplacementStatus } = locationHandler.getLocationInfo(reason);
return checkReplacementStatus?.(reason);
},
};
const unexpectedHandler = {
getMessage: (reason) => reason?.error?.description ?? reason?.message,
isServerError: (reason) => {
const isClientError = reason?.error?.code && reason.error.code !== reason?.serverError?.code;
if (isClientError) {
return !isClientError;
}
return Boolean(reason?.error?.serverError?.code);
},
};
const redirectActionHandler = {
AUTH: (handlerKey) => {
const redirect = handler.getRedirectUrl(handlerKey);
ShopbySkin.utils.removeOpenIdDormantCallback();
ShopbySkin.utils.signOut({
redirect,
replace: true,
});
},
COMMON: (handlerKey) => {
handler.redirect(handlerKey);
},
};
// eslint-disable-next-line complexity
const goNext = (next, replacementStatus) => {
if (next !== -1) {
if (replacementStatus) {
location.replace(next);
} else {
location.href = next;
}
return;
}
if (history.state && history.state.idx === 0) {
location.href = '/';
return;
}
if (!document.referrer || location.href === document.referrer) {
history.back();
return;
}
if (ShopbySkin.utils.isSignedIn() && document.referrer.includes('sign-in.html?from=')) {
location.href = '/';
return;
}
location.href = document.referrer;
};
const goHome = (reason) => {
const isServerError = unexpectedHandler.isServerError(reason);
if (!isServerError) {
return;
}
location.href = '/';
};
// eslint-disable-next-line complexity
const handleRejection = ({ reason }) => {
const serviceErrorKey = handler.getServiceErrorKey(reason);
if (serviceErrorKey) {
handler.redirect(serviceErrorKey);
return;
}
const handlerKey = handler.getHandlerKey(reason);
if (handlerKey) {
ShopbySkin.EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'CAUTION',
message: `${reason.error.description}`,
onClose: () => {
const redirectAction = redirectActionHandler[handlerKey];
if (redirectAction) {
redirectAction(handlerKey);
} else {
redirectActionHandler.COMMON(handlerKey);
}
},
});
return;
}
const handlerConfirm = handler.getHandlerConfirmKey(reason);
if (handlerConfirm) {
ShopbySkin.EventManager.fire('MODAL_CONFIRM_OPEN', {
noticeType: 'CAUTION',
message: `${handlerConfirm?.message}`,
confirmLabel: handlerConfirm.confirmLabel,
cancelLabel: handlerConfirm.cancelLabel,
onConfirm: handlerConfirm.onConfirm,
});
return;
}
const handlerMyPayAuthError = handler.getHandlerMyPayAuthErrorKey(reason);
if (handlerMyPayAuthError) {
const { nextPath, message } = handlerMyPayAuthError;
ShopbySkin.EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'CAUTION',
message: `${message}`,
onClose: () => {
const redirectAction = redirectActionHandler[nextPath];
if (redirectAction) {
redirectAction(nextPath);
} else {
redirectActionHandler.COMMON(nextPath);
}
},
});
return;
}
const handlerAppCardAuthError = handler.getHandlerAppCardAuthErrorKey(reason);
if (handlerAppCardAuthError) {
const { nextPath, message } = handlerAppCardAuthError;
ShopbySkin.EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'CAUTION',
message: `${message}`,
onClose: () => {
const redirectAction = redirectActionHandler[nextPath];
if (redirectAction) {
redirectAction(nextPath);
return;
}
if (nextPath) {
goNext(nextPath, true);
}
},
});
return;
}
const next = locationHandler.getNextPath(reason);
const replacementStatus = locationHandler.getReplacementStatus(reason);
const errorMessage = unexpectedHandler.getMessage(reason);
if (errorMessage) {
ShopbySkin.EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'CAUTION',
message: `${errorMessage}`,
label: '확인',
onClose: () => {
if (locationHandler.isExceptError(reason)) {
return;
}
if (reason.code === 'CEDI007') {
location.replace('/');
return;
}
if (next) {
goNext(next, replacementStatus);
} else {
goHome(reason);
}
},
});
} else {
console.error(reason);
}
};
const handleError = ({ error }) => {
if (error?.code && error?.message) {
ShopbySkin.EventManager.fire('MODAL_ALERT_OPEN', {
message: error?.message,
label: '확인',
});
} else {
console.error(error?.message);
}
};
window.addEventListener('unhandledrejection', handleRejection);
window.addEventListener('error', handleError);
})();