Advertisement
aldikhan13

nestjs custom api response

May 13th, 2025
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TypeScript 3.00 KB | Source Code | 0 0
  1. import { HttpStatus as status } from '@nestjs/common'
  2. import { OutgoingMessage } from 'node:http'
  3. import { Response } from 'express'
  4.  
  5. import { IResponse } from '~/domain/interfaces/common.interface'
  6. import { Logger } from '~/infrastructure/common/helpers/logger.helper'
  7. import { ELoggerType } from '~/domain/enums/common.enum'
  8.  
  9. const errorCodeMap: Record<number, string> = {
  10.   500: 'GENERAL_ERROR',
  11.   502: 'SERVICE_ERROR',
  12.   503: 'SERVICE_UNAVAILABLE',
  13.   504: 'SERVICE_TIMEOUT',
  14.   409: 'DUPLICATE_RESOURCE',
  15.   422: 'INVALID_REQUEST',
  16.   412: 'REQUEST_COULD_NOT_BE_PROCESSED',
  17.   403: 'ACCESS_DENIED',
  18.   401: 'UNAUTHORIZED_TOKEN',
  19.   404: 'UNKNOWN_RESOURCE',
  20. }
  21.  
  22. const defaultErrorCode = 'GENERAL_ERROR'
  23. const defaultErrorMessage = 'Application is busy, please try again later!'
  24.  
  25. const handleErrorLogging = (error: Error): void => {
  26.   const message = `
  27.     =============================================
  28.     ======== Response Exception [Error] =========
  29.     =============================================
  30.  
  31.       name: ${error.name}
  32.       message: ${error.message}
  33.       stack: ${error.stack}
  34.  
  35.     =============================================
  36.     =============================================
  37.     =============================================
  38.   `
  39.   Logger.log('AppErrorException', ELoggerType.ERROR, message, error)
  40. }
  41.  
  42. const createErrorResponse = (error: Error): Partial<IResponse> => {
  43.   const statCode = status.INTERNAL_SERVER_ERROR
  44.   const errCode = errorCodeMap[statCode] || defaultErrorCode
  45.   const errorMessage = error.message || defaultErrorMessage
  46.   return { stat_code: statCode, err_code: errCode, error: errorMessage }
  47. }
  48.  
  49. const createApiResponse = (options: Partial<IResponse>): Partial<IResponse> => {
  50.   let apiResponse: Partial<IResponse> = { ...options }
  51.  
  52.   if (!options.stat_code && !options.message && !options.error) {
  53.     apiResponse.err_code = defaultErrorCode
  54.     apiResponse.error = defaultErrorMessage
  55.   } else if (options.errors) {
  56.     apiResponse = { errors: options.errors }
  57.   } else {
  58.     const statCode = options.stat_code || status.INTERNAL_SERVER_ERROR
  59.     apiResponse.stat_code = statCode
  60.     apiResponse.err_code = errorCodeMap[statCode] || defaultErrorCode
  61.     apiResponse.error = options.error || defaultErrorMessage
  62.   }
  63.  
  64.   for (const key in apiResponse) {
  65.     if (apiResponse[key] === undefined && key !== 'info') {
  66.       delete apiResponse[key]
  67.     }
  68.   }
  69.  
  70.   return apiResponse
  71. }
  72.  
  73. export const response = <T = any>(options: Partial<IResponse> | Error, res?: Response): T => {
  74.   let apiResponse: Partial<IResponse> = {}
  75.  
  76.   if (options instanceof Error) {
  77.     handleErrorLogging(options)
  78.     apiResponse = createErrorResponse(options)
  79.   } else {
  80.     apiResponse = createApiResponse(options)
  81.   }
  82.  
  83.   if (res instanceof OutgoingMessage) {
  84.     const statusCode = apiResponse.errors ? status.UNPROCESSABLE_ENTITY : apiResponse.stat_code || status.INTERNAL_SERVER_ERROR
  85.     return res.status(statusCode).json(apiResponse) as any
  86.   }
  87.  
  88.   return apiResponse as T
  89. }
  90.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement