mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-23 12:02:10 +03:00
Better errors handling (#8835)
- [ ] Catch this specific `500` error - [ ] Make sure catched `500` errors are sent to sentry for the Cloud version - [ ] Hide the option to sync email with google in this situation where the according env var is missing - [x] Add Worskpace information to all catched errors for better debugging fix #8607
This commit is contained in:
parent
32194a88b3
commit
7e4277fbe4
@ -114,8 +114,13 @@ export class GraphQLConfigService
|
|||||||
email: user.email,
|
email: user.email,
|
||||||
firstName: user.firstName,
|
firstName: user.firstName,
|
||||||
lastName: user.lastName,
|
lastName: user.lastName,
|
||||||
workspaceId: workspace?.id,
|
}
|
||||||
workspaceDisplayName: workspace?.displayName,
|
: undefined,
|
||||||
|
workspace
|
||||||
|
? {
|
||||||
|
id: workspace.id,
|
||||||
|
displayName: workspace.displayName,
|
||||||
|
activationStatus: workspace.activationStatus,
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { ExecutionContext, Injectable } from '@nestjs/common';
|
import { ExecutionContext, Injectable } from '@nestjs/common';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
|
|
||||||
import {
|
|
||||||
AuthException,
|
|
||||||
AuthExceptionCode,
|
|
||||||
} from 'src/engine/core-modules/auth/auth.exception';
|
|
||||||
import { GoogleAPIsOauthExchangeCodeForTokenStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-exchange-code-for-token.auth.strategy';
|
import { GoogleAPIsOauthExchangeCodeForTokenStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-exchange-code-for-token.auth.strategy';
|
||||||
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
|
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
|
||||||
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
|
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
|
||||||
|
import {
|
||||||
|
EnvironmentException,
|
||||||
|
EnvironmentExceptionCode,
|
||||||
|
} from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||||
@ -41,9 +41,9 @@ export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
|
|||||||
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
|
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
|
||||||
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
|
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
|
||||||
) {
|
) {
|
||||||
throw new AuthException(
|
throw new EnvironmentException(
|
||||||
'Google apis auth is not enabled',
|
'Google apis auth is not enabled',
|
||||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
EnvironmentExceptionCode.ENVIRONMENT_VARIABLES_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { ExecutionContext, Injectable } from '@nestjs/common';
|
import { ExecutionContext, Injectable } from '@nestjs/common';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
|
|
||||||
import {
|
|
||||||
AuthException,
|
|
||||||
AuthExceptionCode,
|
|
||||||
} from 'src/engine/core-modules/auth/auth.exception';
|
|
||||||
import { GoogleAPIsOauthRequestCodeStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-request-code.auth.strategy';
|
import { GoogleAPIsOauthRequestCodeStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-request-code.auth.strategy';
|
||||||
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
|
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
|
||||||
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
|
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
|
||||||
|
import {
|
||||||
|
EnvironmentException,
|
||||||
|
EnvironmentExceptionCode,
|
||||||
|
} from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||||
@ -41,9 +41,9 @@ export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
|
|||||||
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
|
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
|
||||||
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
|
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
|
||||||
) {
|
) {
|
||||||
throw new AuthException(
|
throw new EnvironmentException(
|
||||||
'Google apis auth is not enabled',
|
'Google apis auth is not enabled',
|
||||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
EnvironmentExceptionCode.ENVIRONMENT_VARIABLES_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@ import { CanActivate, Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
import {
|
|
||||||
AuthException,
|
|
||||||
AuthExceptionCode,
|
|
||||||
} from 'src/engine/core-modules/auth/auth.exception';
|
|
||||||
import { GoogleStrategy } from 'src/engine/core-modules/auth/strategies/google.auth.strategy';
|
import { GoogleStrategy } from 'src/engine/core-modules/auth/strategies/google.auth.strategy';
|
||||||
|
import {
|
||||||
|
EnvironmentException,
|
||||||
|
EnvironmentExceptionCode,
|
||||||
|
} from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -15,9 +15,9 @@ export class GoogleProviderEnabledGuard implements CanActivate {
|
|||||||
|
|
||||||
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
||||||
if (!this.environmentService.get('AUTH_GOOGLE_ENABLED')) {
|
if (!this.environmentService.get('AUTH_GOOGLE_ENABLED')) {
|
||||||
throw new AuthException(
|
throw new EnvironmentException(
|
||||||
'Google auth is not enabled',
|
'Google auth is not enabled',
|
||||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
EnvironmentExceptionCode.ENVIRONMENT_VARIABLES_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@ import { CanActivate, Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
import {
|
|
||||||
AuthException,
|
|
||||||
AuthExceptionCode,
|
|
||||||
} from 'src/engine/core-modules/auth/auth.exception';
|
|
||||||
import { MicrosoftStrategy } from 'src/engine/core-modules/auth/strategies/microsoft.auth.strategy';
|
import { MicrosoftStrategy } from 'src/engine/core-modules/auth/strategies/microsoft.auth.strategy';
|
||||||
|
import {
|
||||||
|
EnvironmentException,
|
||||||
|
EnvironmentExceptionCode,
|
||||||
|
} from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -15,9 +15,9 @@ export class MicrosoftProviderEnabledGuard implements CanActivate {
|
|||||||
|
|
||||||
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
||||||
if (!this.environmentService.get('AUTH_MICROSOFT_ENABLED')) {
|
if (!this.environmentService.get('AUTH_MICROSOFT_ENABLED')) {
|
||||||
throw new AuthException(
|
throw new EnvironmentException(
|
||||||
'Microsoft auth is not enabled',
|
'Microsoft auth is not enabled',
|
||||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
EnvironmentExceptionCode.ENVIRONMENT_VARIABLES_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@ import { CanActivate, Injectable } from '@nestjs/common';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AuthException,
|
EnvironmentException,
|
||||||
AuthExceptionCode,
|
EnvironmentExceptionCode,
|
||||||
} from 'src/engine/core-modules/auth/auth.exception';
|
} from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -16,9 +16,9 @@ export class SSOProviderEnabledGuard implements CanActivate {
|
|||||||
|
|
||||||
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
||||||
if (!this.environmentService.get('ENTERPRISE_KEY')) {
|
if (!this.environmentService.get('ENTERPRISE_KEY')) {
|
||||||
throw new AuthException(
|
throw new EnvironmentException(
|
||||||
'Enterprise key must be defined to use SSO',
|
'Enterprise key must be defined to use SSO',
|
||||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
EnvironmentExceptionCode.ENVIRONMENT_VARIABLES_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,13 +2,14 @@ import { HttpService } from '@nestjs/axios';
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
|
||||||
|
import { isDefined } from 'class-validator';
|
||||||
import FileType from 'file-type';
|
import FileType from 'file-type';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { isDefined } from 'class-validator';
|
|
||||||
|
|
||||||
import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface';
|
import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface';
|
||||||
|
|
||||||
|
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
|
||||||
import {
|
import {
|
||||||
AuthException,
|
AuthException,
|
||||||
AuthExceptionCode,
|
AuthExceptionCode,
|
||||||
@ -18,6 +19,11 @@ import {
|
|||||||
compareHash,
|
compareHash,
|
||||||
hashPassword,
|
hashPassword,
|
||||||
} from 'src/engine/core-modules/auth/auth.util';
|
} from 'src/engine/core-modules/auth/auth.util';
|
||||||
|
import {
|
||||||
|
EnvironmentException,
|
||||||
|
EnvironmentExceptionCode,
|
||||||
|
} from 'src/engine/core-modules/environment/environment.exception';
|
||||||
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service';
|
import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service';
|
||||||
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
|
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
|
||||||
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
||||||
@ -26,9 +32,7 @@ import {
|
|||||||
Workspace,
|
Workspace,
|
||||||
WorkspaceActivationStatus,
|
WorkspaceActivationStatus,
|
||||||
} from 'src/engine/core-modules/workspace/workspace.entity';
|
} from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
|
||||||
import { getImageBufferFromUrl } from 'src/utils/image';
|
import { getImageBufferFromUrl } from 'src/utils/image';
|
||||||
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
|
|
||||||
|
|
||||||
export type SignInUpServiceInput = {
|
export type SignInUpServiceInput = {
|
||||||
email: string;
|
email: string;
|
||||||
@ -298,9 +302,9 @@ export class SignInUpService {
|
|||||||
picture: SignInUpServiceInput['picture'];
|
picture: SignInUpServiceInput['picture'];
|
||||||
}) {
|
}) {
|
||||||
if (this.environmentService.get('IS_SIGN_UP_DISABLED')) {
|
if (this.environmentService.get('IS_SIGN_UP_DISABLED')) {
|
||||||
throw new AuthException(
|
throw new EnvironmentException(
|
||||||
'Sign up is disabled',
|
'Sign up is disabled',
|
||||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
EnvironmentExceptionCode.ENVIRONMENT_VARIABLES_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@ import {
|
|||||||
AuthContext,
|
AuthContext,
|
||||||
JwtPayload,
|
JwtPayload,
|
||||||
} from 'src/engine/core-modules/auth/types/auth-context.type';
|
} from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||||
|
import {
|
||||||
|
EnvironmentException,
|
||||||
|
EnvironmentExceptionCode,
|
||||||
|
} from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
@ -42,9 +46,9 @@ export class AccessTokenService {
|
|||||||
const expiresIn = this.environmentService.get('ACCESS_TOKEN_EXPIRES_IN');
|
const expiresIn = this.environmentService.get('ACCESS_TOKEN_EXPIRES_IN');
|
||||||
|
|
||||||
if (!expiresIn) {
|
if (!expiresIn) {
|
||||||
throw new AuthException(
|
throw new EnvironmentException(
|
||||||
'Expiration time for access token is not set',
|
'Expiration time for access token is not set',
|
||||||
AuthExceptionCode.INTERNAL_SERVER_ERROR,
|
EnvironmentExceptionCode.ENVIRONMENT_VARIABLES_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
|
import { EnvironmentException } from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ describe('LoginTokenService', () => {
|
|||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
service.generateLoginToken('test@example.com'),
|
service.generateLoginToken('test@example.com'),
|
||||||
).rejects.toThrow(AuthException);
|
).rejects.toThrow(EnvironmentException);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { addMilliseconds } from 'date-fns';
|
import { addMilliseconds } from 'date-fns';
|
||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
|
|
||||||
import {
|
|
||||||
AuthException,
|
|
||||||
AuthExceptionCode,
|
|
||||||
} from 'src/engine/core-modules/auth/auth.exception';
|
|
||||||
import { AuthToken } from 'src/engine/core-modules/auth/dto/token.entity';
|
import { AuthToken } from 'src/engine/core-modules/auth/dto/token.entity';
|
||||||
|
import {
|
||||||
|
EnvironmentException,
|
||||||
|
EnvironmentExceptionCode,
|
||||||
|
} from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ export class LoginTokenService {
|
|||||||
const expiresIn = this.environmentService.get('LOGIN_TOKEN_EXPIRES_IN');
|
const expiresIn = this.environmentService.get('LOGIN_TOKEN_EXPIRES_IN');
|
||||||
|
|
||||||
if (!expiresIn) {
|
if (!expiresIn) {
|
||||||
throw new AuthException(
|
throw new EnvironmentException(
|
||||||
'Expiration time for access token is not set',
|
'Expiration time for access token is not set',
|
||||||
AuthExceptionCode.INTERNAL_SERVER_ERROR,
|
EnvironmentExceptionCode.ENVIRONMENT_VARIABLES_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
|
import { EnvironmentException } from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ describe('TransientTokenService', () => {
|
|||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
service.generateTransientToken('member-id', 'user-id', 'workspace-id'),
|
service.generateTransientToken('member-id', 'user-id', 'workspace-id'),
|
||||||
).rejects.toThrow(AuthException);
|
).rejects.toThrow(EnvironmentException);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { addMilliseconds } from 'date-fns';
|
import { addMilliseconds } from 'date-fns';
|
||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
|
|
||||||
import {
|
|
||||||
AuthException,
|
|
||||||
AuthExceptionCode,
|
|
||||||
} from 'src/engine/core-modules/auth/auth.exception';
|
|
||||||
import { AuthToken } from 'src/engine/core-modules/auth/dto/token.entity';
|
import { AuthToken } from 'src/engine/core-modules/auth/dto/token.entity';
|
||||||
|
import {
|
||||||
|
EnvironmentException,
|
||||||
|
EnvironmentExceptionCode,
|
||||||
|
} from 'src/engine/core-modules/environment/environment.exception';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
||||||
|
|
||||||
@ -32,9 +32,9 @@ export class TransientTokenService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!expiresIn) {
|
if (!expiresIn) {
|
||||||
throw new AuthException(
|
throw new EnvironmentException(
|
||||||
'Expiration time for access token is not set',
|
'Expiration time for access token is not set',
|
||||||
AuthExceptionCode.INTERNAL_SERVER_ERROR,
|
EnvironmentExceptionCode.ENVIRONMENT_VARIABLES_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
import { CustomException } from 'src/utils/custom-exception';
|
||||||
|
|
||||||
|
export class EnvironmentException extends CustomException {
|
||||||
|
code: EnvironmentExceptionCode;
|
||||||
|
constructor(message: string, code: EnvironmentExceptionCode) {
|
||||||
|
super(message, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum EnvironmentExceptionCode {
|
||||||
|
ENVIRONMENT_VARIABLES_NOT_FOUND = 'ENVIRONMENT_VARIABLES_NOT_FOUND',
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import { ExceptionHandlerUser } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-user.interface';
|
|
||||||
import { ExceptionHandlerOptions } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-options.interface';
|
import { ExceptionHandlerOptions } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-options.interface';
|
||||||
|
|
||||||
import { ExceptionHandlerDriverInterface } from 'src/engine/core-modules/exception-handler/interfaces';
|
import { ExceptionHandlerDriverInterface } from 'src/engine/core-modules/exception-handler/interfaces';
|
||||||
@ -18,11 +17,4 @@ export class ExceptionHandlerConsoleDriver
|
|||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
captureMessage(message: string, user?: ExceptionHandlerUser): void {
|
|
||||||
console.group('Message Captured');
|
|
||||||
console.info(user);
|
|
||||||
console.info(message);
|
|
||||||
console.groupEnd();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
|
|
||||||
import { ExceptionHandlerOptions } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-options.interface';
|
import { ExceptionHandlerOptions } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-options.interface';
|
||||||
import { ExceptionHandlerUser } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-user.interface';
|
|
||||||
|
|
||||||
import { ExceptionHandlerDriverInterface } from 'src/engine/core-modules/exception-handler/interfaces';
|
import { ExceptionHandlerDriverInterface } from 'src/engine/core-modules/exception-handler/interfaces';
|
||||||
|
|
||||||
@ -24,14 +23,16 @@ export class ExceptionHandlerSentryDriver
|
|||||||
scope.setExtra('document', options.document);
|
scope.setExtra('document', options.document);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options?.workspace) {
|
||||||
|
scope.setExtra('workspace', options.workspace);
|
||||||
|
}
|
||||||
|
|
||||||
if (options?.user) {
|
if (options?.user) {
|
||||||
scope.setUser({
|
scope.setUser({
|
||||||
id: options.user.id,
|
id: options.user.id,
|
||||||
email: options.user.email,
|
email: options.user.email,
|
||||||
firstName: options.user.firstName,
|
firstName: options.user.firstName,
|
||||||
lastName: options.user.lastName,
|
lastName: options.user.lastName,
|
||||||
workspaceId: options.user.workspaceId,
|
|
||||||
workspaceDisplayName: options.user.workspaceDisplayName,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,21 +70,4 @@ export class ExceptionHandlerSentryDriver
|
|||||||
|
|
||||||
return eventIds;
|
return eventIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
captureMessage(message: string, user?: ExceptionHandlerUser) {
|
|
||||||
Sentry.captureMessage(message, (scope) => {
|
|
||||||
if (user) {
|
|
||||||
scope.setUser({
|
|
||||||
id: user.id,
|
|
||||||
email: user.email,
|
|
||||||
firstName: user.firstName,
|
|
||||||
lastName: user.lastName,
|
|
||||||
workspaceId: user.workspaceId,
|
|
||||||
workspaceDisplayName: user.workspaceDisplayName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return scope;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import { ExceptionHandlerOptions } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-options.interface';
|
import { ExceptionHandlerOptions } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-options.interface';
|
||||||
import { ExceptionHandlerUser } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-user.interface';
|
|
||||||
|
|
||||||
export interface ExceptionHandlerDriverInterface {
|
export interface ExceptionHandlerDriverInterface {
|
||||||
captureExceptions(
|
captureExceptions(
|
||||||
exceptions: ReadonlyArray<any>,
|
exceptions: ReadonlyArray<any>,
|
||||||
options?: ExceptionHandlerOptions,
|
options?: ExceptionHandlerOptions,
|
||||||
): string[];
|
): string[];
|
||||||
captureMessage(message: string, user?: ExceptionHandlerUser): void;
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { OperationTypeNode } from 'graphql';
|
import { OperationTypeNode } from 'graphql';
|
||||||
|
|
||||||
import { ExceptionHandlerUser } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-user.interface';
|
import { ExceptionHandlerUser } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-user.interface';
|
||||||
|
import { ExceptionHandlerWorkspace } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-workspace.interface';
|
||||||
|
|
||||||
export interface ExceptionHandlerOptions {
|
export interface ExceptionHandlerOptions {
|
||||||
operation?: {
|
operation?: {
|
||||||
@ -9,4 +10,5 @@ export interface ExceptionHandlerOptions {
|
|||||||
};
|
};
|
||||||
document?: string;
|
document?: string;
|
||||||
user?: ExceptionHandlerUser | null;
|
user?: ExceptionHandlerUser | null;
|
||||||
|
workspace?: ExceptionHandlerWorkspace | null;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,4 @@ export interface ExceptionHandlerUser {
|
|||||||
email?: string;
|
email?: string;
|
||||||
firstName?: string;
|
firstName?: string;
|
||||||
lastName?: string;
|
lastName?: string;
|
||||||
workspaceId?: string;
|
|
||||||
workspaceDisplayName?: string;
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
export interface ExceptionHandlerWorkspace {
|
||||||
|
id?: string;
|
||||||
|
displayName?: string;
|
||||||
|
activationStatus?: string;
|
||||||
|
createdAt?: string;
|
||||||
|
}
|
@ -8,10 +8,10 @@ import { GraphQLError, Kind, OperationDefinitionNode, print } from 'graphql';
|
|||||||
|
|
||||||
import { GraphQLContext } from 'src/engine/api/graphql/graphql-config/interfaces/graphql-context.interface';
|
import { GraphQLContext } from 'src/engine/api/graphql/graphql-config/interfaces/graphql-context.interface';
|
||||||
|
|
||||||
|
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||||
import { generateGraphQLErrorFromError } from 'src/engine/core-modules/graphql/utils/generate-graphql-error-from-error.util';
|
import { generateGraphQLErrorFromError } from 'src/engine/core-modules/graphql/utils/generate-graphql-error-from-error.util';
|
||||||
import { BaseGraphQLError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { BaseGraphQLError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { shouldCaptureException } from 'src/engine/core-modules/graphql/utils/should-capture-exception.util';
|
import { shouldCaptureException } from 'src/engine/core-modules/graphql/utils/should-capture-exception.util';
|
||||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
|
||||||
|
|
||||||
type GraphQLErrorHandlerHookOptions = {
|
type GraphQLErrorHandlerHookOptions = {
|
||||||
/**
|
/**
|
||||||
@ -93,6 +93,14 @@ export const useGraphQLErrorHandlerHook = <
|
|||||||
},
|
},
|
||||||
document,
|
document,
|
||||||
user,
|
user,
|
||||||
|
workspace: {
|
||||||
|
id: args.contextValue.req.workspace?.id,
|
||||||
|
displayName: args.contextValue.req.workspace?.displayName,
|
||||||
|
createdAt:
|
||||||
|
args.contextValue.req.workspace?.createdAt.toISOString(),
|
||||||
|
activationStatus:
|
||||||
|
args.contextValue.req.workspace?.activationStatus,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3,7 +3,9 @@ import { HttpException } from '@nestjs/common';
|
|||||||
import { GraphQLError } from 'graphql';
|
import { GraphQLError } from 'graphql';
|
||||||
|
|
||||||
import { ExceptionHandlerUser } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-user.interface';
|
import { ExceptionHandlerUser } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-user.interface';
|
||||||
|
import { ExceptionHandlerWorkspace } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-workspace.interface';
|
||||||
|
|
||||||
|
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||||
import {
|
import {
|
||||||
AuthenticationError,
|
AuthenticationError,
|
||||||
BaseGraphQLError,
|
BaseGraphQLError,
|
||||||
@ -15,7 +17,6 @@ import {
|
|||||||
TimeoutError,
|
TimeoutError,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
|
||||||
|
|
||||||
const graphQLPredefinedExceptions = {
|
const graphQLPredefinedExceptions = {
|
||||||
400: ValidationError,
|
400: ValidationError,
|
||||||
@ -42,8 +43,9 @@ export const handleExceptionAndConvertToGraphQLError = (
|
|||||||
exception: Error,
|
exception: Error,
|
||||||
exceptionHandlerService: ExceptionHandlerService,
|
exceptionHandlerService: ExceptionHandlerService,
|
||||||
user?: ExceptionHandlerUser,
|
user?: ExceptionHandlerUser,
|
||||||
|
workspace?: ExceptionHandlerWorkspace,
|
||||||
): BaseGraphQLError => {
|
): BaseGraphQLError => {
|
||||||
handleException(exception, exceptionHandlerService, user);
|
handleException(exception, exceptionHandlerService, user, workspace);
|
||||||
|
|
||||||
return convertExceptionToGraphQLError(exception);
|
return convertExceptionToGraphQLError(exception);
|
||||||
};
|
};
|
||||||
@ -74,12 +76,13 @@ const handleException = (
|
|||||||
exception: Error,
|
exception: Error,
|
||||||
exceptionHandlerService: ExceptionHandlerService,
|
exceptionHandlerService: ExceptionHandlerService,
|
||||||
user?: ExceptionHandlerUser,
|
user?: ExceptionHandlerUser,
|
||||||
|
workspace?: ExceptionHandlerWorkspace,
|
||||||
): void => {
|
): void => {
|
||||||
if (shouldFilterException(exception)) {
|
if (shouldFilterException(exception)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
exceptionHandlerService.captureExceptions([exception], { user });
|
exceptionHandlerService.captureExceptions([exception], { user, workspace });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const convertExceptionToGraphQLError = (
|
export const convertExceptionToGraphQLError = (
|
||||||
|
@ -78,8 +78,8 @@ export class CalendarEventListFetchCronJob {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.exceptionHandlerService.captureExceptions([error], {
|
this.exceptionHandlerService.captureExceptions([error], {
|
||||||
user: {
|
workspace: {
|
||||||
workspaceId: activeWorkspace.id,
|
id: activeWorkspace.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,8 @@ export class CalendarEventsImportCronJob {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.exceptionHandlerService.captureExceptions([error], {
|
this.exceptionHandlerService.captureExceptions([error], {
|
||||||
user: {
|
workspace: {
|
||||||
workspaceId: activeWorkspace.id,
|
id: activeWorkspace.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,8 @@ export class CalendarOngoingStaleCronJob {
|
|||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.exceptionHandlerService.captureExceptions([error], {
|
this.exceptionHandlerService.captureExceptions([error], {
|
||||||
user: {
|
workspace: {
|
||||||
workspaceId: activeWorkspace.id,
|
id: activeWorkspace.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -79,8 +79,8 @@ export class MessagingMessageListFetchCronJob {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.exceptionHandlerService.captureExceptions([error], {
|
this.exceptionHandlerService.captureExceptions([error], {
|
||||||
user: {
|
workspace: {
|
||||||
workspaceId: activeWorkspace.id,
|
id: activeWorkspace.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -76,8 +76,8 @@ export class MessagingMessagesImportCronJob {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.exceptionHandlerService.captureExceptions([error], {
|
this.exceptionHandlerService.captureExceptions([error], {
|
||||||
user: {
|
workspace: {
|
||||||
workspaceId: activeWorkspace.id,
|
id: activeWorkspace.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,8 @@ export class MessagingOngoingStaleCronJob {
|
|||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.exceptionHandlerService.captureExceptions([error], {
|
this.exceptionHandlerService.captureExceptions([error], {
|
||||||
user: {
|
workspace: {
|
||||||
workspaceId: activeWorkspace.id,
|
id: activeWorkspace.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -82,8 +82,8 @@ export class MessagingMessageChannelSyncStatusMonitoringCronJob {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.exceptionHandlerService.captureExceptions([error], {
|
this.exceptionHandlerService.captureExceptions([error], {
|
||||||
user: {
|
workspace: {
|
||||||
workspaceId: activeWorkspace.id,
|
id: activeWorkspace.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user