Merged PR 584: エラーログが意図した通りに出ていないところがありそうな問題を解消する

## 概要
[Task2934: エラーログが意図した通りに出ていないところがありそうな問題を解消する](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2934)

- 何をどう変更したか、追加したライブラリなど
error=Errorのログ表示をerror=××Error(エラーの原因)となるように実装

## レビューポイント
- 特にレビューしてほしい箇所
特になし

## 動作確認状況
- ユニットテスト

## 相談(必須レビュアーの方に)
今回の実装のみではまだ解消できていない箇所がいくつかみられました。
以下にその解消できなかったログをいくつかピックアップします。

ERROR [TasksService] error=Error: There is no AuthorId for the API executor.
ERROR [FilesService] error=Error: blob failed
ERROR [FilesService] error=Error: container not found.
ERROR [UsersService] error=Error: ADB2C error
ERROR [UsersService] error=Error: user not found
ERROR [UsersService] error=Error: sort criteria not found
ERROR [UsersService] error=Error: sort criteria not found
ERROR [UsersService] error=Error: The value stored in the DB is invalid.

原因としては、throw new ××Errorではなく、throw new Errorで実装されていました。
interface Error {
    name: string;
    message: string;
    stack?: string;
}

interface ErrorConstructor {
    new(message?: string): Error;
    (message?: string): Error;
    readonly prototype: Error;
}
上記の実装により返却されるメッセージがErrorになっているため解消されていないと考えています。

以上の事象について対応するかしないかということと、対応する場合は、どのように対応していくかをご意見いただきたいです。
本タスクで対応というよりも別タスクとして対応とMISOは想定しています。
This commit is contained in:
水本 祐希 2023-11-20 00:49:00 +00:00
parent d7bb56af54
commit 446b9365f2
21 changed files with 369 additions and 87 deletions

View File

@ -1,6 +1,21 @@
// Role文字列想定外エラー
export class RoleUnexpectedError extends Error {}
export class RoleUnexpectedError extends Error {
constructor(message: string) {
super(message);
this.name = 'RoleUnexpectedError';
}
}
// Tier範囲想定外エラー
export class TierUnexpectedError extends Error {}
export class TierUnexpectedError extends Error {
constructor(message: string) {
super(message);
this.name = 'TierUnexpectedError';
}
}
// トークン形式不正エラー
export class InvalidTokenFormatError extends Error {}
export class InvalidTokenFormatError extends Error {
constructor(message: string) {
super(message);
this.name = 'InvalidTokenFormatError';
}
}

View File

@ -1,12 +1,42 @@
// 音声ファイル不在エラー
export class AudioFileNotFoundError extends Error {}
export class AudioFileNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'AudioFileNotFoundError';
}
}
// テンプレートファイル不在エラー
export class TemplateFileNotFoundError extends Error {}
export class TemplateFileNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'TemplateFileNotFoundError';
}
}
// Account不一致エラー
export class AccountNotMatchError extends Error {}
export class AccountNotMatchError extends Error {
constructor(message: string) {
super(message);
this.name = 'AccountNotMatchError';
}
}
// Status不一致エラー
export class StatusNotMatchError extends Error {}
export class StatusNotMatchError extends Error {
constructor(message: string) {
super(message);
this.name = 'StatusNotMatchError';
}
}
// Author不一致エラー
export class AuthorUserNotMatchError extends Error {}
export class AuthorUserNotMatchError extends Error {
constructor(message: string) {
super(message);
this.name = 'AuthorUserNotMatchError';
}
}
// TypistUser不一致エラー
export class TypistUserNotMatchError extends Error {}
export class TypistUserNotMatchError extends Error {
constructor(message: string) {
super(message);
this.name = 'TypistUserNotMatchError';
}
}

View File

@ -128,7 +128,9 @@ describe('LicensesService', () => {
it('POナンバー重複時、エラーとなる', async () => {
const lisencesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
lisencesRepositoryMockValue.order = new PoNumberAlreadyExistError();
lisencesRepositoryMockValue.order = new PoNumberAlreadyExistError(
`This PoNumber already used`,
);
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const accountsRepositoryMockValue =
makeDefaultAccountsRepositoryMockValue();
@ -260,8 +262,9 @@ describe('LicensesService', () => {
it('カードライセンス取り込みに失敗した場合、エラーになる(ライセンスが存在しないエラー)', async () => {
const lisencesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
lisencesRepositoryMockValue.activateCardLicense =
new LicenseNotExistError();
lisencesRepositoryMockValue.activateCardLicense = new LicenseNotExistError(
`License not exist`,
);
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const accountsRepositoryMockValue =
makeDefaultAccountsRepositoryMockValue();
@ -284,7 +287,7 @@ describe('LicensesService', () => {
const lisencesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
lisencesRepositoryMockValue.activateCardLicense =
new LicenseKeyAlreadyActivatedError();
new LicenseKeyAlreadyActivatedError(`License already activated`);
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const accountsRepositoryMockValue =
makeDefaultAccountsRepositoryMockValue();

View File

@ -1,2 +1,7 @@
// ロール不正エラー
export class InvalidRoleError extends Error {}
export class InvalidRoleError extends Error {
constructor(message: string) {
super(message);
this.name = 'InvalidRoleError';
}
}

View File

@ -330,8 +330,9 @@ describe('UsersService.confirmUserAndInitPassword', () => {
const configMockValue = makeDefaultConfigValue();
const sortCriteriaRepositoryMockValue =
makeDefaultSortCriteriaRepositoryMockValue();
usersRepositoryMockValue.updateUserVerified =
new EmailAlreadyVerifiedError();
usersRepositoryMockValue.updateUserVerified = new EmailAlreadyVerifiedError(
`Email already verified user`,
);
const service = await makeUsersServiceMock(
usersRepositoryMockValue,

View File

@ -22,8 +22,7 @@ export class RedisService {
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.set.name} | params: { ` +
`ttl: ${ttl}
};`,
`ttl: ${ttl} };`,
);
try {
@ -34,6 +33,8 @@ export class RedisService {
await this.cacheManager.set(key, value, { ttl: ttl } as any);
} catch (error) {
this.logger.error(`[${context.getTrackingId()}] ${error}`);
} finally {
this.logger.log(`[OUT] [${context.getTrackingId()}] ${this.set.name}`);
}
}
@ -50,8 +51,7 @@ export class RedisService {
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.mset.name} | params: { ` +
`ttl: ${ttl}
};`,
`ttl: ${ttl} };`,
);
try {
@ -62,6 +62,8 @@ export class RedisService {
}
} catch (error) {
this.logger.error(`[${context.getTrackingId()}] ${error}`);
} finally {
this.logger.log(`[OUT] [${context.getTrackingId()}] ${this.mset.name}`);
}
}
@ -80,6 +82,8 @@ export class RedisService {
} catch (error) {
this.logger.error(`[${context.getTrackingId()}] ${error}`);
return undefined;
} finally {
this.logger.log(`[OUT] [${context.getTrackingId()}] ${this.get.name}`);
}
}
@ -109,6 +113,8 @@ export class RedisService {
} catch (error) {
this.logger.error(`[${context.getTrackingId()}] ${error}`);
return [];
} finally {
this.logger.log(`[OUT] [${context.getTrackingId()}] ${this.mget.name}`);
}
}
@ -123,6 +129,8 @@ export class RedisService {
await this.cacheManager.del(key);
} catch (error) {
this.logger.error(`[${context.getTrackingId()}] ${error}`);
} finally {
this.logger.log(`[OUT] [${context.getTrackingId()}] ${this.del.name}`);
}
}
}

View File

@ -216,7 +216,7 @@ export class AccountsRepositoryService {
});
if (!account) {
throw new AccountNotFoundError();
throw new AccountNotFoundError(`Account is Not Found.`);
}
return account;
}
@ -525,7 +525,7 @@ export class AccountsRepositoryService {
},
});
if (!ownAccount) {
throw new AccountNotFoundError();
throw new AccountNotFoundError(`Account is Not Found.`);
}
// 自アカウントのライセンス注文状況を取得する
@ -947,7 +947,7 @@ export class AccountsRepositoryService {
// ワークタイプが存在しない場合はエラー
if (!worktype) {
throw new WorktypeIdNotFoundError('Worktype is not found. id: ${id}');
throw new WorktypeIdNotFoundError(`Worktype is not found. id: ${id}`);
}
}

View File

@ -1,8 +1,28 @@
// アカウント未発見エラー
export class AccountNotFoundError extends Error {}
export class AccountNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'AccountNotFoundError';
}
}
// ディーラーアカウント未存在エラー
export class DealerAccountNotFoundError extends Error {}
export class DealerAccountNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'DealerAccountNotFoundError';
}
}
// 管理者ユーザ未存在エラー
export class AdminUserNotFoundError extends Error {}
export class AdminUserNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'AdminUserNotFoundError';
}
}
// アカウントロックエラー
export class AccountLockedError extends Error {}
export class AccountLockedError extends Error {
constructor(message: string) {
super(message);
this.name = 'AccountLockedError';
}
}

View File

@ -1,38 +1,108 @@
// POナンバーがすでに存在するエラー
export class PoNumberAlreadyExistError extends Error {}
export class PoNumberAlreadyExistError extends Error {
constructor(message: string) {
super(message);
this.name = 'PoNumberAlreadyExistError';
}
}
// 取り込むカードライセンスが存在しないエラー
export class LicenseNotExistError extends Error {}
export class LicenseNotExistError extends Error {
constructor(message: string) {
super(message);
this.name = 'LicenseNotExistError';
}
}
// 取り込むライセンスが既に取り込み済みのエラー
export class LicenseKeyAlreadyActivatedError extends Error {}
export class LicenseKeyAlreadyActivatedError extends Error {
constructor(message: string) {
super(message);
this.name = 'LicenseKeyAlreadyActivatedError';
}
}
// 注文不在エラー
export class OrderNotFoundError extends Error {}
export class OrderNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'OrderNotFoundError';
}
}
// 注文発行済エラー
export class AlreadyIssuedError extends Error {}
export class AlreadyIssuedError extends Error {
constructor(message: string) {
super(message);
this.name = 'AlreadyIssuedError';
}
}
// ライセンス不足エラー
export class LicensesShortageError extends Error {}
export class LicensesShortageError extends Error {
constructor(message: string) {
super(message);
this.name = 'LicensesShortageError';
}
}
// ライセンス有効期限切れエラー
export class LicenseExpiredError extends Error {}
export class LicenseExpiredError extends Error {
constructor(message: string) {
super(message);
this.name = 'LicenseExpiredError';
}
}
// ライセンス割り当て不可エラー
export class LicenseUnavailableError extends Error {}
export class LicenseUnavailableError extends Error {
constructor(message: string) {
super(message);
this.name = 'LicenseUnavailableError';
}
}
// ライセンス割り当て解除済みエラー
export class LicenseAlreadyDeallocatedError extends Error {}
export class LicenseAlreadyDeallocatedError extends Error {
constructor(message: string) {
super(message);
this.name = 'LicenseAlreadyDeallocatedError';
}
}
// 注文キャンセル失敗エラー
export class CancelOrderFailedError extends Error {}
export class CancelOrderFailedError extends Error {
constructor(message: string) {
super(message);
this.name = 'CancelOrderFailedError';
}
}
// ライセンス発行キャンセル不可エラー(ステータスが変えられている場合)
export class AlreadyLicenseStatusChangedError extends Error {}
export class AlreadyLicenseStatusChangedError extends Error {
constructor(message: string) {
super(message);
this.name = 'AlreadyLicenseStatusChangedError';
}
}
// ライセンス発行キャンセル不可エラー(発行から一定期間経過した場合)
export class CancellationPeriodExpiredError extends Error {}
export class CancellationPeriodExpiredError extends Error {
constructor(message: string) {
super(message);
this.name = 'CancellationPeriodExpiredError';
}
}
// ライセンス発行キャンセル不可エラー(発行したライセンスが割り当てされている場合)
export class AlreadyLicenseAllocatedError extends Error {}
export class AlreadyLicenseAllocatedError extends Error {
constructor(message: string) {
super(message);
this.name = 'AlreadyLicenseAllocatedError';
}
}
// ライセンス未割当エラー
export class LicenseNotAllocatedError extends Error {}
export class LicenseNotAllocatedError extends Error {
constructor(message: string) {
super(message);
this.name = 'LicenseNotAllocatedError';
}
}

View File

@ -73,7 +73,7 @@ export class LicensesRepositoryService {
});
// 重複があった場合はエラーを返却する
if (isPoNumberDuplicated) {
throw new PoNumberAlreadyExistError();
throw new PoNumberAlreadyExistError(`This PoNumber already used.`);
}
const repo = entityManager.getRepository(LicenseOrder);
@ -239,14 +239,14 @@ export class LicensesRepositoryService {
this.logger.error(
`card license key not exist. card_licence_key: ${licenseKey}`,
);
throw new LicenseNotExistError();
throw new LicenseNotExistError(`License not exist.`);
}
// 既に取り込み済みならエラー
if (targetCardLicense.activated_at) {
this.logger.error(
`card license already activated. card_licence_key: ${licenseKey}`,
);
throw new LicenseKeyAlreadyActivatedError();
throw new LicenseKeyAlreadyActivatedError(`License already activated.`);
}
const licensesRepo = entityManager.getRepository(License);
@ -262,7 +262,7 @@ export class LicensesRepositoryService {
this.logger.error(
`license not exist. licence_id: ${targetCardLicense.license_id}`,
);
throw new LicenseNotExistError();
throw new LicenseNotExistError(`License not exist.`);
}
// ライセンステーブルを更新する

View File

@ -34,7 +34,7 @@ export class SortCriteriaRepositoryService {
});
// 運用上はあり得ないが、プログラム上発生しうるのでエラーとして処理
if (!targetSortCriteria) {
throw new Error('sort criteria not found ');
throw new Error('sort criteria not found.');
}
targetSortCriteria.parameter = parameter;
@ -60,7 +60,7 @@ export class SortCriteriaRepositoryService {
});
// 運用上はあり得ないが、プログラム上発生しうるのでエラーとして処理
if (!sortCriteria) {
throw new Error('sort criteria not found ');
throw new Error('sort criteria not found.');
}
return sortCriteria;

View File

@ -1,18 +1,63 @@
// タイピストグループ未発見エラー
export class TypistUserGroupNotFoundError extends Error {}
export class TypistUserGroupNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'TypistUserGroupNotFoundError';
}
}
// タイピストユーザー未発見エラー
export class TypistUserNotFoundError extends Error {}
export class TypistUserNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'TypistUserNotFoundError';
}
}
// タスク未発見エラー
export class TasksNotFoundError extends Error {}
export class TasksNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'TasksNotFoundError';
}
}
// タスクAuthorID不一致エラー
export class TaskAuthorIdNotMatchError extends Error {}
export class TaskAuthorIdNotMatchError extends Error {
constructor(message: string) {
super(message);
this.name = 'TaskAuthorIdNotMatchError';
}
}
// チェックアウト権限未発見エラー
export class CheckoutPermissionNotFoundError extends Error {}
export class CheckoutPermissionNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'CheckoutPermissionNotFoundError';
}
}
// Status不一致エラー
export class StatusNotMatchError extends Error {}
export class StatusNotMatchError extends Error {
constructor(message: string) {
super(message);
this.name = 'StatusNotMatchError';
}
}
// TypistUser不一致エラー
export class TypistUserNotMatchError extends Error {}
export class TypistUserNotMatchError extends Error {
constructor(message: string) {
super(message);
this.name = 'TypistUserNotMatchError';
}
}
// Account不一致エラー
export class AccountNotMatchError extends Error {}
export class AccountNotMatchError extends Error {
constructor(message: string) {
super(message);
this.name = 'AccountNotMatchError';
}
}
// タスクチェックアウト済みエラー
export class AlreadyHasInProgressTaskError extends Error {}
export class AlreadyHasInProgressTaskError extends Error {
constructor(message: string) {
super(message);
this.name = 'AlreadyHasInProgressTaskError';
}
}

View File

@ -190,7 +190,7 @@ export class TasksRepositoryService {
);
}
if (!isTaskStatus(task.status)) {
throw new Error('invalid task status');
throw new Error('invalid task status.');
}
// ステータスチェック
if (!permittedSourceStatus.includes(task.status)) {
@ -340,7 +340,7 @@ export class TasksRepositoryService {
);
}
if (!isTaskStatus(task.status)) {
throw new Error('invalid task status');
throw new Error('invalid task status.');
}
// ステータスチェック
if (!permittedSourceStatus.includes(task.status)) {

View File

@ -1,2 +1,7 @@
// テンプレートファイルが存在しないエラー
export class TemplateFileNotExistError extends Error {}
export class TemplateFileNotExistError extends Error {
constructor(message: string) {
super(message);
this.name = 'TemplateFileNotExistError';
}
}

View File

@ -1,4 +1,14 @@
// タイピストグループが存在しないエラー
export class TypistGroupNotExistError extends Error {}
export class TypistGroupNotExistError extends Error {
constructor(message: string) {
super(message);
this.name = 'TypistGroupNotExistError';
}
}
// typistIdが不正な場合のエラー
export class TypistIdInvalidError extends Error {}
export class TypistIdInvalidError extends Error {
constructor(message: string) {
super(message);
this.name = 'TypistIdInvalidError';
}
}

View File

@ -1,16 +1,56 @@
// Email検証済みエラー
export class EmailAlreadyVerifiedError extends Error {}
export class EmailAlreadyVerifiedError extends Error {
constructor(message: string) {
super(message);
this.name = 'EmailAlreadyVerifiedError';
}
}
// ユーザー未発見エラー
export class UserNotFoundError extends Error {}
export class UserNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'UserNotFoundError';
}
}
// AuthorID重複エラー
export class AuthorIdAlreadyExistsError extends Error {}
export class AuthorIdAlreadyExistsError extends Error {
constructor(message: string) {
super(message);
this.name = 'AuthorIdAlreadyExistsError';
}
}
// 不正なRole変更エラー
export class InvalidRoleChangeError extends Error {}
export class InvalidRoleChangeError extends Error {
constructor(message: string) {
super(message);
this.name = 'InvalidRoleChangeError';
}
}
// 暗号化パスワード不足エラー
export class EncryptionPasswordNeedError extends Error {}
export class EncryptionPasswordNeedError extends Error {
constructor(message: string) {
super(message);
this.name = 'EncryptionPasswordNeedError';
}
}
// 利用規約バージョン情報不在エラー
export class TermInfoNotFoundError extends Error {}
export class TermInfoNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'TermInfoNotFoundError';
}
}
// 利用規約バージョンパラメータ不在エラー
export class UpdateTermsVersionNotSetError extends Error {}
export class UpdateTermsVersionNotSetError extends Error {
constructor(message: string) {
super(message);
this.name = 'UpdateTermsVersionNotSetError';
}
}
// 代行操作不許可エラー
export class DelegationNotAllowedError extends Error {}
export class DelegationNotAllowedError extends Error {
constructor(message: string) {
super(message);
this.name = 'DelegationNotAllowedError';
}
}

View File

@ -136,7 +136,7 @@ export class UsersRepositoryService {
});
if (!user) {
throw new UserNotFoundError();
throw new UserNotFoundError(`User not Found.`);
}
return user;
}
@ -189,7 +189,7 @@ export class UsersRepositoryService {
// 運用上ユーザがいないことはあり得ないが、プログラム上発生しうるのでエラーとして処理
if (!targetUser) {
throw new UserNotFoundError();
throw new UserNotFoundError(`User not Found.`);
}
// ユーザーのロールがNoneの場合以外はロールを変更できない
@ -267,11 +267,11 @@ export class UsersRepositoryService {
// 運用上ユーザがいないことはあり得ないが、プログラム上発生しうるのでエラーとして処理
if (!targetUser) {
throw new UserNotFoundError();
throw new UserNotFoundError(`User not Found.`);
}
if (targetUser.email_verified) {
throw new EmailAlreadyVerifiedError();
throw new EmailAlreadyVerifiedError(`Email already verified user.`);
}
targetUser.email_verified = true;
@ -299,11 +299,11 @@ export class UsersRepositoryService {
// 運用上ユーザがいないことはあり得ないが、プログラム上発生しうるのでエラーとして処理
if (!targetUser) {
throw new UserNotFoundError();
throw new UserNotFoundError(`User not Found.`);
}
if (targetUser.email_verified) {
throw new EmailAlreadyVerifiedError();
throw new EmailAlreadyVerifiedError(`Email already verified user.`);
}
targetUser.email_verified = true;
@ -382,7 +382,7 @@ export class UsersRepositoryService {
// 運用上ユーザがいないことはあり得ないが、プログラム上発生しうるのでエラーとして処理
if (!user) {
throw new UserNotFoundError();
throw new UserNotFoundError(`User not Found.`);
}
const typists = await repo.find({
@ -456,7 +456,7 @@ export class UsersRepositoryService {
});
if (!user) {
throw new UserNotFoundError();
throw new UserNotFoundError(`User not Found.`);
}
if (!user.account) {
throw new AccountNotFoundError('Account is Not Found.');

View File

@ -1,4 +1,14 @@
// AuthorIDとWorktypeIDのペア重複エラー
export class AuthorIdAndWorktypeIdPairAlreadyExistsError extends Error {}
export class AuthorIdAndWorktypeIdPairAlreadyExistsError extends Error {
constructor(message: string) {
super(message);
this.name = 'AuthorIdAndWorktypeIdPairAlreadyExistsError';
}
}
// Workflow存在エラー
export class WorkflowNotFoundError extends Error {}
export class WorkflowNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'WorkflowNotFoundError';
}
}

View File

@ -97,7 +97,7 @@ export class WorkflowsRepositoryService {
where: { account_id: accountId, id: templateId },
});
if (!template) {
throw new TemplateFileNotExistError('template not found');
throw new TemplateFileNotExistError('template not found.');
}
}
@ -144,7 +144,7 @@ export class WorkflowsRepositoryService {
});
if (workflow.length !== 0) {
throw new AuthorIdAndWorktypeIdPairAlreadyExistsError(
'workflow already exists',
'workflow already exists.',
);
}
@ -288,7 +288,7 @@ export class WorkflowsRepositoryService {
});
if (duplicateWorkflow.length !== 0) {
throw new AuthorIdAndWorktypeIdPairAlreadyExistsError(
'workflow already exists',
'workflow already exists.',
);
}
}

View File

@ -1,8 +1,28 @@
// WorktypeID重複エラー
export class WorktypeIdAlreadyExistsError extends Error {}
export class WorktypeIdAlreadyExistsError extends Error {
constructor(message: string) {
super(message);
this.name = 'WorktypeIdAlreadyExistsError';
}
}
// WorktypeID登録上限エラー
export class WorktypeIdMaxCountError extends Error {}
export class WorktypeIdMaxCountError extends Error {
constructor(message: string) {
super(message);
this.name = 'WorktypeIdMaxCountError';
}
}
// WorktypeID不在エラー
export class WorktypeIdNotFoundError extends Error {}
export class WorktypeIdNotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = 'WorktypeIdNotFoundError';
}
}
// WorktypeID使用中エラー
export class WorktypeIdInUseError extends Error {}
export class WorktypeIdInUseError extends Error {
constructor(message: string) {
super(message);
this.name = 'WorktypeIdInUseError';
}
}

View File

@ -39,7 +39,7 @@ export class WorktypesRepositoryService {
// 運用上アカウントがいないことはあり得ないが、プログラム上発生しうるのでエラーとして処理
if (!account) {
throw new AccountNotFoundError();
throw new AccountNotFoundError('Account is Not Found.');
}
const worktypes = await WorktypeRepo.find({