mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 22:02:16 +00:00
refactor(withings): extract recordWithingsSyncFailure for sync.ts catch-block dedup
The W6 swap from `isWithingsRefreshReauthFailure(message)` to the typed `classifyError(err)` + `classificationToFailureKind()` chain left two byte-identical 14-LOC catch-blocks in `sync.ts` — one in `getValidToken`, one in `syncUserMeasurements`. Extract the shared recording shape into `recordWithingsSyncFailure(userId, err)` so the two call sites collapse to a single `await`. Sync-activity / sync- sleep migration to typed errors (W6 deferred to v1.4.43) gets a single one-line catch block as a bonus when it lands. No behaviour change — the 140 withings / integrations unit tests still pin every failure path.
This commit is contained in:
1 parent
d2adf265e4
commit
7c9fb09098
1 file changed
+26
-29
+26
-29
@@ -115,23 +115,7 @@ export async function getValidToken(userId: string): Promise<{
|
||||
};
|
||||
} catch (err) {
|
||||
getEvent()?.addWarning(`Token refresh failed for user ${userId}: ${err}`);
|
||||
// v1.4.42 W6 — the typed `WithingsApiError` carries the
|
||||
// classification verdict directly; the regex fallback in
|
||||
// `classifyError` handles plain `Error` instances (e.g. a
|
||||
// pg-boss job retry that lost the prototype during JSON
|
||||
// round-trip).
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
const classification = classifyError(err);
|
||||
await recordSyncFailure({
|
||||
userId,
|
||||
integration: "withings",
|
||||
kind: classificationToFailureKind(classification),
|
||||
message,
|
||||
errorCode:
|
||||
err instanceof WithingsApiError
|
||||
? err.withingsStatus?.toString()
|
||||
: extractWithingsStatus(message),
|
||||
});
|
||||
await recordWithingsSyncFailure(userId, err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -193,18 +177,7 @@ export async function syncUserMeasurements(
|
||||
try {
|
||||
measures = await fetchMeasurements(tokenInfo.accessToken, startDate);
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
const classification = classifyError(err);
|
||||
await recordSyncFailure({
|
||||
userId,
|
||||
integration: "withings",
|
||||
kind: classificationToFailureKind(classification),
|
||||
message,
|
||||
errorCode:
|
||||
err instanceof WithingsApiError
|
||||
? err.withingsStatus?.toString()
|
||||
: extractWithingsStatus(message),
|
||||
});
|
||||
await recordWithingsSyncFailure(userId, err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -307,6 +280,30 @@ export async function syncUserMeasurements(
|
||||
* `reauth_required` → `reauth_required` (park at `error_reauth`)
|
||||
* `persistent` → `persistent` (audited; next sync still runs)
|
||||
*/
|
||||
/**
|
||||
* v1.4.42 — shared failure-recording shape for the two Withings sync
|
||||
* catch-blocks. The typed `WithingsApiError` carries the classification
|
||||
* verdict directly; `classifyError`'s regex fallback handles plain
|
||||
* `Error` instances (e.g. a pg-boss job retry that lost the prototype
|
||||
* during the JSON round-trip).
|
||||
*/
|
||||
async function recordWithingsSyncFailure(
|
||||
userId: string,
|
||||
err: unknown,
|
||||
): Promise<void> {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
await recordSyncFailure({
|
||||
userId,
|
||||
integration: "withings",
|
||||
kind: classificationToFailureKind(classifyError(err)),
|
||||
message,
|
||||
errorCode:
|
||||
err instanceof WithingsApiError
|
||||
? err.withingsStatus?.toString()
|
||||
: extractWithingsStatus(message),
|
||||
});
|
||||
}
|
||||
|
||||
export function classificationToFailureKind(
|
||||
classification: WithingsClassification,
|
||||
): FailureKind {
|
||||
|
||||
Reference in new issue
Block a user