Fix env not optional + serverless logging (#15186)
Several fixes after discussing with @BOHEUS - set applicationManifest env key optional - fix server local serverless function logging (introduces a new env variable `SERVERLESS_LOGS_ENABLED` defaulting to false)
This commit is contained in:
+59
@@ -0,0 +1,59 @@
|
||||
import {
|
||||
type ArgumentsHost,
|
||||
Catch,
|
||||
type ExceptionFilter,
|
||||
} from '@nestjs/common';
|
||||
|
||||
import type { Response } from 'express';
|
||||
|
||||
import {
|
||||
RouteTriggerException,
|
||||
RouteTriggerExceptionCode,
|
||||
} from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception';
|
||||
import type { CustomException } from 'src/utils/custom-exception';
|
||||
import { HttpExceptionHandlerService } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
|
||||
|
||||
@Catch(RouteTriggerException)
|
||||
export class RouteTriggerRestApiExceptionFilter implements ExceptionFilter {
|
||||
constructor(
|
||||
private readonly httpExceptionHandlerService: HttpExceptionHandlerService,
|
||||
) {}
|
||||
|
||||
catch(exception: RouteTriggerException, host: ArgumentsHost) {
|
||||
const ctx = host.switchToHttp();
|
||||
const response = ctx.getResponse<Response>();
|
||||
|
||||
switch (exception.code) {
|
||||
case RouteTriggerExceptionCode.WORKSPACE_NOT_FOUND:
|
||||
case RouteTriggerExceptionCode.ROUTE_NOT_FOUND:
|
||||
case RouteTriggerExceptionCode.TRIGGER_NOT_FOUND:
|
||||
case RouteTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND:
|
||||
return this.httpExceptionHandlerService.handleError(
|
||||
exception as CustomException,
|
||||
response,
|
||||
404,
|
||||
);
|
||||
case RouteTriggerExceptionCode.FORBIDDEN_EXCEPTION:
|
||||
return this.httpExceptionHandlerService.handleError(
|
||||
exception as CustomException,
|
||||
response,
|
||||
403,
|
||||
);
|
||||
case RouteTriggerExceptionCode.SERVERLESS_FUNCTION_EXECUTION_ERROR:
|
||||
return this.httpExceptionHandlerService.handleError(
|
||||
exception as CustomException,
|
||||
response,
|
||||
500,
|
||||
);
|
||||
case RouteTriggerExceptionCode.ROUTE_ALREADY_EXIST:
|
||||
case RouteTriggerExceptionCode.ROUTE_PATH_ALREADY_EXIST:
|
||||
default: {
|
||||
return this.httpExceptionHandlerService.handleError(
|
||||
exception as CustomException,
|
||||
response,
|
||||
400,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -8,9 +8,12 @@ export class RouteTriggerException extends CustomException {
|
||||
}
|
||||
|
||||
export enum RouteTriggerExceptionCode {
|
||||
WORKSPACE_NOT_FOUND = 'WORKSPACE_NOT_FOUND',
|
||||
ROUTE_NOT_FOUND = 'ROUTE_NOT_FOUND',
|
||||
ROUTE_ALREADY_EXIST = 'ROUTE_ALREADY_EXIST',
|
||||
ROUTE_INVALID = 'ROUTE_INVALID',
|
||||
ROUTE_PATH_ALREADY_EXIST = 'ROUTE_PATH_ALREADY_EXIST',
|
||||
TRIGGER_NOT_FOUND = 'TRIGGER_NOT_FOUND',
|
||||
SERVERLESS_FUNCTION_NOT_FOUND = 'SERVERLESS_FUNCTION_NOT_FOUND',
|
||||
ROUTE_ALREADY_EXIST = 'ROUTE_ALREADY_EXIST',
|
||||
ROUTE_PATH_ALREADY_EXIST = 'ROUTE_PATH_ALREADY_EXIST',
|
||||
FORBIDDEN_EXCEPTION = 'FORBIDDEN_EXCEPTION',
|
||||
SERVERLESS_FUNCTION_EXECUTION_ERROR = 'SERVERLESS_FUNCTION_EXECUTION_ERROR',
|
||||
}
|
||||
|
||||
+8
-16
@@ -6,6 +6,7 @@ import {
|
||||
Post,
|
||||
Put,
|
||||
Req,
|
||||
UseFilters,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
|
||||
@@ -14,60 +15,51 @@ import { Request } from 'express';
|
||||
import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard';
|
||||
import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { RouteTriggerService } from 'src/engine/metadata-modules/route-trigger/route-trigger.service';
|
||||
import { formatServerlessControllerResponse } from 'src/engine/metadata-modules/route-trigger/utils/format-serverless-controller-response';
|
||||
import { RouteTriggerRestApiExceptionFilter } from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger-rest-api-exception-filter';
|
||||
|
||||
@Controller('s')
|
||||
@UseGuards(PublicEndpointGuard)
|
||||
@UseFilters(RouteTriggerRestApiExceptionFilter)
|
||||
export class RouteTriggerController {
|
||||
constructor(private readonly routeTriggerService: RouteTriggerService) {}
|
||||
|
||||
@Get('*')
|
||||
async get(@Req() request: Request) {
|
||||
const result = await this.routeTriggerService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.GET,
|
||||
});
|
||||
|
||||
return formatServerlessControllerResponse(result);
|
||||
}
|
||||
|
||||
@Post('*')
|
||||
async post(@Req() request: Request) {
|
||||
const result = await this.routeTriggerService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.POST,
|
||||
});
|
||||
|
||||
return formatServerlessControllerResponse(result);
|
||||
}
|
||||
|
||||
@Put('*')
|
||||
async put(@Req() request: Request) {
|
||||
const result = await this.routeTriggerService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.PUT,
|
||||
});
|
||||
|
||||
return formatServerlessControllerResponse(result);
|
||||
}
|
||||
|
||||
@Patch('*')
|
||||
async patch(@Req() request: Request) {
|
||||
const result = await this.routeTriggerService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.PATCH,
|
||||
});
|
||||
|
||||
return formatServerlessControllerResponse(result);
|
||||
}
|
||||
|
||||
@Delete('*')
|
||||
async delete(@Req() request: Request) {
|
||||
const result = await this.routeTriggerService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.DELETE,
|
||||
});
|
||||
|
||||
return formatServerlessControllerResponse(result);
|
||||
}
|
||||
}
|
||||
|
||||
+39
-20
@@ -1,8 +1,4 @@
|
||||
import {
|
||||
ForbiddenException,
|
||||
Injectable,
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
@@ -16,11 +12,11 @@ import {
|
||||
} from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/access-token.service';
|
||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||
import {
|
||||
AuthException,
|
||||
AuthExceptionCode,
|
||||
} from 'src/engine/core-modules/auth/auth.exception';
|
||||
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
||||
import {
|
||||
RouteTriggerException,
|
||||
RouteTriggerExceptionCode,
|
||||
} from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception';
|
||||
|
||||
@Injectable()
|
||||
export class RouteTriggerService {
|
||||
@@ -51,9 +47,9 @@ export class RouteTriggerService {
|
||||
|
||||
assertIsDefinedOrThrow(
|
||||
workspace,
|
||||
new AuthException(
|
||||
new RouteTriggerException(
|
||||
'Workspace not found',
|
||||
AuthExceptionCode.WORKSPACE_NOT_FOUND,
|
||||
RouteTriggerExceptionCode.WORKSPACE_NOT_FOUND,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -81,7 +77,10 @@ export class RouteTriggerService {
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundException('No Route trigger found');
|
||||
throw new RouteTriggerException(
|
||||
'No Route trigger found',
|
||||
RouteTriggerExceptionCode.TRIGGER_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
private async validateWorkspaceFromRequest({
|
||||
@@ -95,11 +94,17 @@ export class RouteTriggerService {
|
||||
await this.accessTokenService.validateTokenByRequest(request);
|
||||
|
||||
if (!isDefined(workspace)) {
|
||||
throw new NotFoundException('Workspace not found');
|
||||
throw new RouteTriggerException(
|
||||
'Workspace not found',
|
||||
RouteTriggerExceptionCode.WORKSPACE_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
if (workspace.id !== workspaceId) {
|
||||
throw new ForbiddenException('Invalid Workspace');
|
||||
throw new RouteTriggerException(
|
||||
'You are not authorized',
|
||||
RouteTriggerExceptionCode.FORBIDDEN_EXCEPTION,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,11 +138,25 @@ export class RouteTriggerService {
|
||||
...routeTriggerWithPathParams.pathParams,
|
||||
};
|
||||
|
||||
return await this.serverlessFunctionService.executeOneServerlessFunction(
|
||||
routeTriggerWithPathParams.routeTrigger.serverlessFunction.id,
|
||||
routeTriggerWithPathParams.routeTrigger.workspaceId,
|
||||
executionParams,
|
||||
'draft',
|
||||
);
|
||||
const result =
|
||||
await this.serverlessFunctionService.executeOneServerlessFunction(
|
||||
routeTriggerWithPathParams.routeTrigger.serverlessFunction.id,
|
||||
routeTriggerWithPathParams.routeTrigger.workspaceId,
|
||||
executionParams,
|
||||
'draft',
|
||||
);
|
||||
|
||||
if (!isDefined(result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result.error) {
|
||||
throw new RouteTriggerException(
|
||||
result.error.errorMessage,
|
||||
RouteTriggerExceptionCode.SERVERLESS_FUNCTION_EXECUTION_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
import { HttpException, HttpStatus } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ServerlessExecuteResult } from 'src/engine/core-modules/serverless/drivers/interfaces/serverless-driver.interface';
|
||||
|
||||
export const formatServerlessControllerResponse = (
|
||||
result?: ServerlessExecuteResult | null,
|
||||
) => {
|
||||
if (!isDefined(result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result.error) {
|
||||
throw new HttpException(
|
||||
{ errorType: result.error.errorType, message: result.error.errorMessage },
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
};
|
||||
Reference in New Issue
Block a user