Контроллер машинописного текста и служебное ПО не работают - PullRequest
0 голосов
/ 03 августа 2020

Здравствуйте, у меня есть репозиторий / службы / контроллеры следующей структуры, и у меня есть промежуточное ПО для форматирования ошибок

мое приложение:

class App {
  public app: express.Application;
  private controllers: IController[];
  constructor() {
    this.app = express();
    this.controllers = [];
    this.startDBConnection();
  }

  private async startDBConnection() {
    try {
      const connection = await createConnection();
      await connection.runMigrations();
      container.register(Connection, { useValue: connection });
      this.listen();
    } catch (error) {
      console.log('Error while connecting to the database', error);
      return error;
    }
  }

  private initializeRoutes() {
    container.resolveAll<IController>('Controller').forEach(controller => {
      console.log(controller.getRouter());
      this.app.use('/', controller.getRouter());
    });
  }

  public listen() {
    this.initializeMiddlewares();
    this.initializeRoutes();
    this.initializeErrorHandling();
    this.app.listen(process.env.SERVER_PORT, () => {
      console.log(`⚡️ App listening on the port ${process.env.SERVER_PORT}`);
    });
  }

  public getServer() {
    return this.app;
  }

  private initializeMiddlewares() {
    this.app.use(cors());
    this.app.use(express.json());
    this.app.use(bodyParser.json());
    this.app.use(cookieParser());
    this.app.get('/favico.ico', (req, res) => {
      res.sendStatus(404);
    });
    this.app.get('/', (req, res) => {
      res.send('Welcome');
    });
  }

  private initializeErrorHandling() {
    this.app.use(
      (err: Error, request: Request, response: Response, _: NextFunction) => {
        console.log('a');
        if (err instanceof CustomExternalError) {
          return response.status(err.statusCode).json(err.error);
        }

        console.log(err);

        return response.status(500).json({
          status: 'error',
          message: 'Internal server error',
        });
      },
    );
  }
}

export default App;

мой контроллер :

@singleton()
export class DepartamentController implements IController {
  private router: Router;
  private path: string;
  private services: DepartamentServices;
  constructor() {
    this.path = '/departament';
    this.router = Router();
    this.services = container.resolve(DepartamentServices);
    this.initializeRoutes();
  }
  private initializeRoutes() {
    this.router.get(`${this.path}`, this.hello);
    this.router.post(`${this.path}/create`, this.createDepartament);
  }
  getPath(): string {
    return this.path;
  }
  getRouter(): Router {
    return this.router;
  }

  private createDepartament = async (request: Request, response: Response) => {
    const data: createDepartament = request.body;
    const Departament = this.services.createDepartament(data);
    response.status(200).json(Departament);
  };

}

моя служба:

import { singleton, inject, injectable } from 'tsyringe';
import { Repository, Connection } from 'typeorm';
import { Employee, User } from '@entities';
import { DepartamentRepository } from '../repositories/index';
import { CustomExternalError } from '@shared/errors/custom.external.error';
import { responseCodes } from '@shared/errors/errors_codes';
import { createDepartament } from '../dtos/createDepartament';
import Joi from '@hapi/joi';
import { validateAndFormat } from '@utils/validateSchema';
import { EmployeeRepository } from '@modules/employees/repositories';

@injectable()
export class DepartamentServices {
  constructor(
    @inject(DepartamentRepository)
    private departamentRepository: DepartamentRepository,
    @inject(EmployeeRepository)
    private employeeRepository: EmployeeRepository,
  ) {}

  public async createDepartament(data: createDepartament) {
    const schema = Joi.object({
      departament_name: Joi.string().min(10).max(30).required().messages({
        'string.base': `invalid`,
        'string.empty': `missing_field`,
        'string.min': `invalid`,
        'any.required': `missing_field`,
      }),
      manager_id: Joi.string()
        .guid({ version: 'uuidv4' })
        .optional()
        .allow(null)
        .messages({
          'string.base': `invalid`,
          'string.guid': `invalid`,
        }),
    });
    const checkFields = validateAndFormat(data, schema, 'Departament');
    throw new CustomExternalError(
      {
        message: 'Validation Failed',
        errors: [
          {
            resource: 'Departament',
            field: data.manager_id,
            code: 'unprocessable',
          },
        ],
      },
      responseCodes.UNPROCESSABLE_ENTITY,
    );

  }
}

и моя настраиваемая ошибка и перечисление:

import { responseCodes } from './errors_codes';
import { responseError } from '@interfaces/IResponse';
export class CustomExternalError {
  constructor(public error: responseError, public statusCode: responseCodes) {
    this.error;
    this.statusCode;
  }
}

перечисление:

export enum responseCodes {
  SUCESS_OK = 200,
  NOT_FOUND = 404,
  FORBIDDEN = 403,
  UNAUTHORIZED = 401,
  UNPROCESSABLE_ENTITY = 422,
}

по какой-то причине, когда я делаю запрос маршрута, чтобы проверить, работает ли мое промежуточное ПО с ошибкой:

, я получаю следующее:

(node:7584) UnhandledPromiseRejectionWarning: #<CustomExternalError>
(node:7584) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:7584) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

но если я вызываю свой throw new Custom error в моем файловом контроллере мое промежуточное ПО работает нормально, а в моем сервисе - нет.

...