Improve sentry grouping (#12007)
This PR attemps at improving sentry grouping and filtering by - Using the exceptionCode as the fingerprint when the error is a customException. For this to work in this PR we are now throwing customExceptions instead of internalServerError deprived of their code. They will still be converted to Internal server errors when sent back as response - Filtering 4xx issues where it was missing (for emailVerification because errors were not handled, for invalid captcha and billing errors because they are httpErrors and not graphqlErrors) --------- Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
import { CustomException } from 'src/utils/custom-exception';
|
||||
|
||||
export class FieldMetadataException extends CustomException {
|
||||
declare code: FieldMetadataExceptionCode;
|
||||
constructor(message: string, code: FieldMetadataExceptionCode) {
|
||||
super(message, code);
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ import {
|
||||
RelationMetadataEntity,
|
||||
RelationMetadataType,
|
||||
} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||
import { InvalidMetadataNameException } from 'src/engine/metadata-modules/utils/exceptions/invalid-metadata-name.exception';
|
||||
import { InvalidMetadataException } from 'src/engine/metadata-modules/utils/exceptions/invalid-metadata.exception';
|
||||
import { exceedsDatabaseIdentifierMaximumLength } from 'src/engine/metadata-modules/utils/validate-database-identifier-length.utils';
|
||||
import { validateFieldNameAvailabilityOrThrow } from 'src/engine/metadata-modules/utils/validate-field-name-availability.utils';
|
||||
import { validateMetadataNameOrThrow } from 'src/engine/metadata-modules/utils/validate-metadata-name.utils';
|
||||
@ -614,7 +614,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
try {
|
||||
validateMetadataNameOrThrow(fieldMetadataInput.name);
|
||||
} catch (error) {
|
||||
if (error instanceof InvalidMetadataNameException) {
|
||||
if (error instanceof InvalidMetadataException) {
|
||||
throw new FieldMetadataException(
|
||||
error.message,
|
||||
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
|
||||
@ -630,7 +630,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
objectMetadata,
|
||||
);
|
||||
} catch (error) {
|
||||
if (error instanceof InvalidMetadataNameException) {
|
||||
if (error instanceof InvalidMetadataException) {
|
||||
throw new FieldMetadataException(
|
||||
`Name "${fieldMetadataInput.name}" is not available, check that it is not duplicating another field's name.`,
|
||||
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
|
||||
|
||||
@ -11,6 +11,14 @@ import {
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { removeFieldMapsFromObjectMetadata } from 'src/engine/metadata-modules/utils/remove-field-maps-from-object-metadata.util';
|
||||
import {
|
||||
WorkspaceMetadataCacheException,
|
||||
WorkspaceMetadataCacheExceptionCode,
|
||||
} from 'src/engine/metadata-modules/workspace-metadata-cache/exceptions/workspace-metadata-cache.exception';
|
||||
import {
|
||||
WorkspaceMetadataVersionException,
|
||||
WorkspaceMetadataVersionExceptionCode,
|
||||
} from 'src/engine/metadata-modules/workspace-metadata-version/exceptions/workspace-metadata-version.exception';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
|
||||
@Injectable()
|
||||
@ -43,9 +51,9 @@ export class FieldMetadataRelationService {
|
||||
await this.workspaceCacheStorageService.getMetadataVersion(workspaceId);
|
||||
|
||||
if (!isDefined(metadataVersion)) {
|
||||
throw new FieldMetadataException(
|
||||
throw new WorkspaceMetadataVersionException(
|
||||
`Metadata version not found for workspace ${workspaceId}`,
|
||||
FieldMetadataExceptionCode.INTERNAL_SERVER_ERROR,
|
||||
WorkspaceMetadataVersionExceptionCode.METADATA_VERSION_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
@ -56,9 +64,9 @@ export class FieldMetadataRelationService {
|
||||
);
|
||||
|
||||
if (!objectMetadataMaps) {
|
||||
throw new FieldMetadataException(
|
||||
throw new WorkspaceMetadataCacheException(
|
||||
`Object metadata map not found for workspace ${workspaceId} and metadata version ${metadataVersion}`,
|
||||
FieldMetadataExceptionCode.INTERNAL_SERVER_ERROR,
|
||||
WorkspaceMetadataCacheExceptionCode.OBJECT_METADATA_MAP_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import {
|
||||
ConflictError,
|
||||
ForbiddenError,
|
||||
InternalServerError,
|
||||
NotFoundError,
|
||||
UserInputError,
|
||||
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
@ -31,8 +30,12 @@ export const fieldMetadataGraphqlApiExceptionHandler = (error: Error) => {
|
||||
case FieldMetadataExceptionCode.FIELD_METADATA_RELATION_NOT_ENABLED:
|
||||
case FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED:
|
||||
case FieldMetadataExceptionCode.LABEL_IDENTIFIER_FIELD_METADATA_ID_NOT_FOUND:
|
||||
default:
|
||||
throw new InternalServerError(error.message);
|
||||
throw error;
|
||||
default: {
|
||||
const _exhaustiveCheck: never = error.code;
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user