From 18c3ef991a85043facd2a606efa838d5398ff40b Mon Sep 17 00:00:00 2001 From: allburov Date: Fri, 19 Aug 2022 10:15:32 +0300 Subject: [PATCH] Handle errors and show fullstack for 500 --- src/api/exception.filter.ts | 30 ++++++++++++++++++++++++++++++ src/main.ts | 2 ++ src/whatsapp.service.ts | 24 ++++++++++++++++++------ 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 src/api/exception.filter.ts diff --git a/src/api/exception.filter.ts b/src/api/exception.filter.ts new file mode 100644 index 00000000..6b7b05ff --- /dev/null +++ b/src/api/exception.filter.ts @@ -0,0 +1,30 @@ +import {ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus,} from '@nestjs/common'; +import {Request, Response} from 'express'; + +@Catch() +export class AllExceptionsFilter implements ExceptionFilter { + catch(exception: HttpException | Error, host: ArgumentsHost): void { + const ctx = host.switchToHttp(); + const response = ctx.getResponse(); + const request = ctx.getRequest(); + + if (exception instanceof HttpException) { + response + .status(exception.getStatus()) + .json(exception.getResponse()); + return + } + + const httpStatus = HttpStatus.INTERNAL_SERVER_ERROR + response + .status(httpStatus) + .json({ + statusCode: httpStatus, + timestamp: new Date().toISOString(), + path: request.url, + error: exception.message, + stack: exception.stack, + }); + + } +} diff --git a/src/main.ts b/src/main.ts index e561b391..830f3bff 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import {NestFactory} from '@nestjs/core'; import {AppModule} from './app.module'; import {DocumentBuilder, SwaggerModule} from "@nestjs/swagger"; import {WhatsappConfigService} from "./config.service"; +import {AllExceptionsFilter} from "./api/exception.filter"; async function bootstrap() { const app = await NestFactory.create(AppModule, { @@ -10,6 +11,7 @@ async function bootstrap() { }); app.enableShutdownHooks(); + app.useGlobalFilters(new AllExceptionsFilter()); const options = new DocumentBuilder() .setTitle('WhatsApp HTTP API') .setDescription('WhatsApp HTTP API that you can configure in a click!') diff --git a/src/whatsapp.service.ts b/src/whatsapp.service.ts index 4a253a67..2e0b3dcb 100644 --- a/src/whatsapp.service.ts +++ b/src/whatsapp.service.ts @@ -1,8 +1,9 @@ import {create, Message, Whatsapp} from "venom-bot"; -import {ConsoleLogger, Injectable, OnApplicationShutdown} from "@nestjs/common"; +import {ConsoleLogger, Injectable, NotFoundException, OnApplicationShutdown} from "@nestjs/common"; import * as path from "path"; import {WhatsappConfigService} from "./config.service"; import {WHATSAPP_DEFAULT_SESSION_NAME} from "./api/all.dto"; +import {UnprocessableEntityException} from "@nestjs/common/exceptions/unprocessable-entity.exception"; import request = require('requestretry'); import mime = require('mime-types'); import fs = require('fs'); @@ -86,13 +87,13 @@ export class WhatsappService { public async getScreenshotOrQRCode(): Promise { if (this.status === WhatsappStatus.STARTING) { - // TODO: raise an error please wait + throw new UnprocessableEntityException(`The session is starting, please try again after few seconds`); } else if (this.status === WhatsappStatus.SCAN_QR_CODE) { return this.getQRCode() } else if (this.status === WhatsappStatus.WORKING) { return await this.whatsapp.page.screenshot() } else { - // TODO: throw unknown status + throw new UnprocessableEntityException(`Unknown status - ${this.status}`); } } @@ -159,6 +160,11 @@ export class WhatsappService { } public getWhatsapp() { + if (this.status != WhatsappStatus.WORKING) { + throw new UnprocessableEntityException( + `The session status is "${this.status}". Please scan QR code first by using GET /screenshot method.`, + ); + } return this.whatsapp } @@ -215,12 +221,18 @@ export class WhatsappSessionManager implements OnApplicationShutdown { } getService(name: string): WhatsappService { - return this.sessions[name] + const session = this.sessions[name] + if (!session) { + throw new NotFoundException( + `We didn't find a session with name "${name}". Please start it first by using POST /sessions/start request`, + ); + } + return session } getSession(name: string): Whatsapp { - // TODO: Check session exists - return this.sessions[name].getWhatsapp() + const service = this.getService(name) + return service.getWhatsapp() } stopSession(name: string) {