Compare commits

...
Author SHA1 Message Date
Sonarly Claude Code f298471f36 fix: handle missing morph relation field in timeline activity for custom objects
https://sonarly.com/issue/15455?type=bug

The timeline activity worker crashes with PostgreSQL error 42703 when processing events for custom objects (e.g., "quote") whose morph relation column does not exist in the database, despite being present in the ORM metadata.

Fix: The bug fix already exists in commit `36934df3bc` (authored 2026-03-16) which adds a `hasTimelineActivityMorphRelationField()` validation check in `TimelineActivityRepository.upsertTimelineActivities()`. It verifies the morph relation field exists in the `timelineActivity` object metadata before constructing queries. If the field is missing (as with the `targetQuoteId` column for custom "quote" objects), it logs a warning and returns early instead of crashing.

No duplicate fix was implemented.
2026-03-17 01:00:36 +00:00
3 changed files with 14 additions and 3 deletions
@@ -1,7 +1,9 @@
export class PostgresException extends Error {
readonly code: string;
constructor(message: string, code: string) {
readonly originalMessage: string | undefined;
constructor(message: string, code: string, originalMessage?: string) {
super(message);
this.code = code;
this.originalMessage = originalMessage;
}
}
@@ -87,6 +87,11 @@ export class ExceptionHandlerSentryDriver
if (exception instanceof PostgresException) {
scope.setTag('postgresSqlErrorCode', exception.code);
if (isDefined(exception.originalMessage)) {
scope.setExtra('originalPostgresMessage', exception.originalMessage);
}
const fingerPrint = [exception.code];
const genericOperationName = getGenericOperationName(
options?.operation?.name,
@@ -96,7 +101,7 @@ export class ExceptionHandlerSentryDriver
fingerPrint.push(genericOperationName);
}
scope.setFingerprint(fingerPrint);
exception.name = exception.message;
exception.name = exception.originalMessage ?? exception.message;
}
if (exception instanceof MessageImportDriverException) {
@@ -62,7 +62,11 @@ export const computeTwentyORMException = async (
isDefined(errorCode) &&
Object.values(POSTGRESQL_ERROR_CODES).includes(errorCode)
) {
throw new PostgresException('Data validation error.', errorCode);
throw new PostgresException(
'Data validation error.',
errorCode,
error.message,
);
}
throw error;
}