samchon / nestia

NestJS Helper Libraries + TypeScript OpenAPI generator
https://nestia.io/
MIT License
1.8k stars 92 forks source link

integrated `@TypedException`. suggest `@TypedExceptions` #789

Closed 8471919 closed 7 months ago

8471919 commented 7 months ago

Feature Request

Thanks for your suggestion. Feel free to just state your idea. Writing the issue, it would better to filling the below items:

I use error message like this.

export const ERROR_MESSAGE = {
  AUTH: {
    FORBIDDEN: {
      code: 403,
      message: '금지된 접근입니다.',
    },
  },
  TOKEN: {
    NOT_FOUND_TOKEN: {
      code: 404,
      message: '토큰을 찾을 수 없습니다.',
    },
  },
} as const;

export type ErrorMessageType = {
  code: number;
  message: string;
};

and setting the ErrorResponseForm type. because Nestia cannot read unnamed type. like... property: CustomType['name']

export type ErrorResponseForm<T extends ErrorMessageType> = {
  success: false;
  timestamp: string & tags.Format<'date-time'>;
  path: string & tags.Format<'url'>;
} & T;

and this is my controller

  @TypedRoute.Get('')
  @TypedException<ErrorResponseForm<typeof ERROR_MESSAGE.AUTH.FORBIDDEN>>(
    ERROR_MESSAGE.AUTH.FORBIDDEN.code,
    ERROR_MESSAGE.AUTH.FORBIDDEN.message,
  )
  @TypedException<
    ErrorResponseForm<typeof ERROR_MESSAGE.TOKEN.NOT_FOUND_TOKEN>
  >(
    ERROR_MESSAGE.TOKEN.NOT_FOUND_TOKEN.code,
    ERROR_MESSAGE.TOKEN.NOT_FOUND_TOKEN.message,
  )
  async getAuthDataWithNoDomainId(
    @User('token') token: string,
  ): Promise<ResponseForm<Dto>> {
     // ...some code
     // in Error case
     throw new BadRequestException(ERROR_MESSAGE.AUTH.FORBIDDEN);
  }

I think if some people use nestia, this style of @TypedException is forced for convenience. so... I suggest to make @TypedExceptions decorator for too many rows using @TypedException.

I tried this code for customizing TypedExceptions decorator. but it didn't work.

import { ErrorMessageType } from 'src/utils/constants';
import { ErrorResponseForm } from '../filters/global.filter';
import { TypedException } from '@nestia/core';
import { applyDecorators } from '@nestjs/common';

export const TypedExceptions = (...errorMessages: ErrorMessageType[]) => {
  const decorators: MethodDecorator[] = [];

  for (const errorMessage of errorMessages) {
    decorators.push(
      TypedException<ErrorResponseForm<typeof errorMessage>>(
        errorMessage.code,
        errorMessage.message,
      ),
    );
  }

  return applyDecorators(...decorators);
};

// @TypedExceptions(ERROR_MESSAGE1, ERROR_MESSAGE2, ERROR_MESSAGE3)

// @TypedException<ERROR_MESSAGE1>()
// @TypedException<ERROR_MESSAGE2>()
// @TypedException<ERROR_MESSAGE3>()

How to use

// controller.ts

@TypedExceptions(ERROR_MESSAGE1,
  {
    code: 400,
    message: 'BadRequest'
  },
  ... // like array
)
async function a() {

}
samchon commented 7 months ago

No way to implement it type safely considering aspects of compiler API.