UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

228 lines (227 loc) 10.9 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MOVIE_TICKET_RESERVE_REQUEST_ERROR_NAME = exports.MongoErrorCode = void 0; exports.isMongoError = isMongoError; exports.handleMongoError = handleMongoError; exports.handleCOAError = handleCOAError; exports.handleCOAReserveTemporarilyError = handleCOAReserveTemporarilyError; exports.handlePecorinoError = handlePecorinoError; exports.handleMvtkReserveError = handleMvtkReserveError; exports.handleAWSError = handleAWSError; /** * エラーハンドラー * 外部サービスと連携している場合に、サービス(API)のエラーを本ドメインのエラーに変換する責任を担います。 */ const http_status_1 = require("http-status"); const factory_1 = require("./factory"); let mongo; var MongoErrorCode; (function (MongoErrorCode) { MongoErrorCode[MongoErrorCode["DuplicateKey"] = 11000] = "DuplicateKey"; MongoErrorCode[MongoErrorCode["MaxTimeMSExpired"] = 50] = "MaxTimeMSExpired"; MongoErrorCode[MongoErrorCode["ExceededTimeLimit"] = 262] = "ExceededTimeLimit"; })(MongoErrorCode || (exports.MongoErrorCode = MongoErrorCode = {})); function isMongoError(error) { return __awaiter(this, void 0, void 0, function* () { if (mongo === undefined) { mongo = (yield Promise.resolve().then(() => require('mongoose'))).mongo; } return (error instanceof mongo.MongoError || error instanceof mongo.MongoServerError); }); } function handleMongoError(error) { return __awaiter(this, void 0, void 0, function* () { if (mongo === undefined) { mongo = (yield Promise.resolve().then(() => require('mongoose'))).mongo; } let handledError = error; if (handledError instanceof mongo.MongoError || handledError instanceof mongo.MongoServerError) { switch (handledError.code) { case MongoErrorCode.DuplicateKey: handledError = new factory_1.errors.AlreadyInUse('', [], `Some fields already in use. code:${handledError.code} message:${handledError.message}`); // no op break; case MongoErrorCode.MaxTimeMSExpired: case MongoErrorCode.ExceededTimeLimit: handledError = new factory_1.errors.GatewayTimeout(`Gateway Timeout. name:${handledError.name} code:${handledError.code} message:${handledError.message}`); break; default: } } if (mongo.BSON.BSONError.isBSONError(handledError)) { handledError = new factory_1.errors.Argument('', handledError.message); } return handledError; }); } /** * 汎用的なCOAエラーハンドリング */ // tslint:disable-next-line:no-any function handleCOAError(error) { var _a; let handledError = error; if (error.name === 'AbortError') { handledError = new factory_1.errors.GatewayTimeout(`Gateway Timeout. name:${error.name} code:${error.code} message:${error.message}`); } if (error.name === 'COAServiceError') { // error.requestOptions.uriを処理 const uri = (_a = error.requestOptions) === null || _a === void 0 ? void 0 : _a.uri; if (error.message === 'ETIMEDOUT' || error.message === 'ESOCKETTIMEDOUT') { handledError = new factory_1.errors.GatewayTimeout(`Timeout. name:${error.name} code:${error.code} message:${error.message} uri:${uri}`); } else { handledError = new factory_1.errors.Internal(`Service Unavailable. name:${error.name} code:${error.code} message:${error.message} uri:${uri}`); } } return handledError; } /** * COA仮予約エラーハンドリング */ // tslint:disable-next-line:no-any function handleCOAReserveTemporarilyError(error) { var _a; let handledError = error; // if (error.message === '座席取得失敗') { // } // メッセージ「既に予約済みです」の場合は、座席の重複とみなす if (error.message === '既に予約済みです') { handledError = new factory_1.errors.AlreadyInUse('offer', ['seatNumber'], 'Seat not available'); } // Chevreが500未満であればクライアントエラーとみなす const reserveServiceHttpStatusCode = error.code; if (Number.isInteger(reserveServiceHttpStatusCode)) { if (reserveServiceHttpStatusCode < http_status_1.INTERNAL_SERVER_ERROR) { handledError = new factory_1.errors.Argument('Event', error.message); } else { const uri = (_a = error.requestOptions) === null || _a === void 0 ? void 0 : _a.uri; if (error.message === 'ETIMEDOUT' || error.message === 'ESOCKETTIMEDOUT') { handledError = new factory_1.errors.GatewayTimeout(`Timeout. name:${error.name} code:${error.code} message:${error.message} uri:${uri}`); } else { handledError = new factory_1.errors.Internal(`Reserve service unavailable. name:${error.name} code:${error.code} message:${error.message} uri:${uri}`); } } } return handledError; } /** * Pecorinoサービスエラーをハンドリングする * 可能であればChevreエラーへ変換します */ // tslint:disable-next-line:no-any function handlePecorinoError(error) { let handledError = error; if (error.name === 'ChevreRequestError' || error.name === 'PecorinoRequestError') { // Pecorino APIのステータスコード4xxをハンドリング // PecorinoAPIのレスポンスステータスコードが4xxであればクライアントエラー const message = `${error.name}:${error.message}`; switch (error.code) { case http_status_1.BAD_REQUEST: // 400 handledError = new factory_1.errors.Argument((typeof error.argumentName === 'string' && error.argumentName.length > 0) ? error.argumentName : 'PecorinoArgument', message); break; case http_status_1.UNAUTHORIZED: // 401 handledError = new factory_1.errors.Unauthorized(message); break; case http_status_1.FORBIDDEN: // 403 handledError = new factory_1.errors.Forbidden(message); break; case http_status_1.NOT_FOUND: // 404 handledError = new factory_1.errors.NotFound(message); break; case http_status_1.TOO_MANY_REQUESTS: // 429 handledError = new factory_1.errors.RateLimitExceeded(message); break; default: handledError = new factory_1.errors.Internal(message); } } return handledError; } exports.MOVIE_TICKET_RESERVE_REQUEST_ERROR_NAME = 'MovieticketReserveRequestError'; /** * ムビチケ着券サービスエラーをハンドリングする * 可能であればChevreエラーへ変換します */ // tslint:disable-next-line:no-any function handleMvtkReserveError(error) { let handledError = error; if (error.name === exports.MOVIE_TICKET_RESERVE_REQUEST_ERROR_NAME) { // ムビチケAPIのステータスコード4xxをハンドリング // ムビチケAPIのレスポンスステータスコードが4xxであればクライアントエラー const message = `${error.name}:${error.message}`; switch (error.code) { case http_status_1.BAD_REQUEST: // 400 handledError = new factory_1.errors.Argument((typeof error.argumentName === 'string' && error.argumentName.length > 0) ? error.argumentName : 'MovieticketReserveArgument', message); break; case http_status_1.UNAUTHORIZED: // 401 handledError = new factory_1.errors.Unauthorized(message); break; case http_status_1.FORBIDDEN: // 403 handledError = new factory_1.errors.Forbidden(message); break; case http_status_1.NOT_FOUND: // 404 handledError = new factory_1.errors.NotFound(message); break; case http_status_1.TOO_MANY_REQUESTS: // 429 handledError = new factory_1.errors.RateLimitExceeded(message); break; // handle 504(2025-04-25~) case http_status_1.GATEWAY_TIMEOUT: // 504 handledError = new factory_1.errors.GatewayTimeout(message); break; default: handledError = new factory_1.errors.Internal(message); } } // タイムアウト設定によって中止されたリクエストの場合 // const uri: string | undefined = error.requestOptions?.uri; if (error.name === 'AbortError') { handledError = new factory_1.errors.GatewayTimeout(`Gateway Timeout. name:${error.name} type:${error.type} message:${error.message}`); } return handledError; } /** * AWSエラーハンドリング */ // tslint:disable-next-line:no-any function handleAWSError(error) { let handledError = error; const message = `${error.name}:${error.message}`; switch (error.name) { case 'InternalErrorException': handledError = new factory_1.errors.Internal(message); break; case 'MissingRequiredParameter': handledError = new factory_1.errors.ArgumentNull('AWSArgument', message); break; case 'InvalidParameterException': handledError = new factory_1.errors.Argument('AWSArgument', message); break; case 'NotAuthorizedException': handledError = new factory_1.errors.Forbidden(message); break; case 'TooManyRequestsException': handledError = new factory_1.errors.RateLimitExceeded(message); break; case 'ResourceNotFoundException': handledError = new factory_1.errors.NotFound('Resource', message); break; case 'UserNotFoundException': handledError = new factory_1.errors.NotFound('User', message); break; default: } return handledError; }