Skip to content

Commit 56f2c5e

Browse files
committed
chore: bugfix for two way no merge and better error handling when merging
Signed-off-by: Uroš Marolt <uros@marolt.me>
1 parent c2aeddf commit 56f2c5e

3 files changed

Lines changed: 41 additions & 11 deletions

File tree

services/apps/cron_service/src/jobs/integrationResultsReporting.job.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,34 @@ const job: IJobDefinition = {
6262
)
6363
).count
6464

65-
// Break down errors by errorMessage + location, enriched with platform info
65+
// Break down errors by errorMessage + location, enriched with platform info.
66+
// When a mergeError is present in metadata, prefer its errorMessage for grouping
67+
// so merge crashes surface as distinct groups rather than collapsing into the
68+
// generic outer errorMessage.
6669
const errorGroups = await dbConnection.any<IErrorGroup>(
6770
`
6871
SELECT
69-
COALESCE(r.error->>'errorMessage', '[no errorMessage]') AS "errorMessage",
70-
COALESCE(r.error->>'location', '[no location]') AS location,
71-
count(*)::int AS count,
72-
round(avg(r.retries), 1)::float AS "avgRetries",
73-
max(r.retries)::int AS "maxRetries",
74-
min(r."createdAt") AS oldest,
75-
max(r."updatedAt") AS newest,
72+
COALESCE(
73+
r.error->'metadata'->>'errorMessage',
74+
r.error->>'errorMessage',
75+
'[no errorMessage]'
76+
) AS "errorMessage",
77+
COALESCE(r.error->>'location', '[no location]') AS location,
78+
count(*)::int AS count,
79+
round(avg(r.retries), 1)::float AS "avgRetries",
80+
max(r.retries)::int AS "maxRetries",
81+
min(r."createdAt") AS oldest,
82+
max(r."updatedAt") AS newest,
7683
string_agg(DISTINCT i.platform, ', ' ORDER BY i.platform) AS platforms
7784
FROM integration.results r
7885
LEFT JOIN integrations i ON i.id = r."integrationId"
7986
WHERE r.state = 'error'
8087
GROUP BY
81-
r.error->>'errorMessage',
88+
COALESCE(
89+
r.error->'metadata'->>'errorMessage',
90+
r.error->>'errorMessage',
91+
'[no errorMessage]'
92+
),
8293
r.error->>'location'
8394
ORDER BY count DESC
8495
LIMIT 20

services/apps/data_sink_worker/src/service/activity.service.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,20 @@ export default class ActivityService extends LoggerBase {
17681768
}
17691769
}
17701770

1771+
if (
1772+
metadata.memberWithIdentity &&
1773+
metadata.memberIdToUpdate &&
1774+
metadata.memberWithIdentity === metadata.memberIdToUpdate
1775+
) {
1776+
// The member already owns the conflicting identity — stale prefetch race.
1777+
// The identity is already present so treat this as a no-op success.
1778+
this.log.warn(
1779+
{ memberId: metadata.memberIdToUpdate, identity: metadata.erroredVerifiedIdentity },
1780+
'Verified identity already belongs to this member (stale prefetch) — treating as success',
1781+
)
1782+
return metadata.memberIdToUpdate as string
1783+
}
1784+
17711785
if (
17721786
metadata.memberWithIdentity &&
17731787
metadata.memberIdToUpdate &&
@@ -1789,16 +1803,22 @@ export default class ActivityService extends LoggerBase {
17891803
return originalId
17901804
} else {
17911805
metadata.noMerge = true
1806+
metadata.errorMessage = 'noMerge blocked — verified identity conflict'
17921807
}
17931808
} catch (err) {
17941809
metadata.mergeError = {
17951810
errorMessage: err?.message ?? '<no error message>',
17961811
errorStack: err?.stack,
17971812
err,
17981813
}
1814+
metadata.errorMessage = 'merge failed — auto-merge threw an error'
17991815
}
18001816
}
18011817

1818+
if (!metadata.errorMessage) {
1819+
metadata.errorMessage = 'verified identity conflict — identity owner not found'
1820+
}
1821+
18021822
return metadata
18031823
}
18041824

services/apps/data_sink_worker/src/service/member.service.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ export async function mergeIfAllowed(
8484
secondaryId: string,
8585
): Promise<boolean> {
8686
const noMergeMemberIds = await getMemberNoMerge(pgQx, [primaryId, secondaryId])
87-
const noMerge = singleOrDefault(
88-
noMergeMemberIds,
87+
const noMerge = noMergeMemberIds.some(
8988
(m) =>
9089
(m.memberId === primaryId && m.noMergeId === secondaryId) ||
9190
(m.memberId === secondaryId && m.noMergeId === primaryId),

0 commit comments

Comments
 (0)