Bug/gh issues fiz (#1103)
* refactor: optimize page loading and data fetching * fix: resolve recurring production runtime errors * feat: add MCP company and customer updates * fix: handle year-end tax adjustments * feat: harden annual report compliance * fix: expand invoice logo and font support * fix: sanitize API route error responses * fix: sanitize user-facing error messages * feat: persist onboarding and tax assessment notices * fix: reduce cloud backup audit churn * feat: refine invoice editor layout * fix: show saved tax adjustments in INK2 * fix: complete annual report API mappings * docs: record operational safeguards and decisions * fix: harden annual report review findings * fix: adjust column span for description based on VAT registration * New css class name
This commit is contained in:
@@ -270,7 +270,7 @@ describe('cloud-backup auto-sync cron', () => {
|
||||
companyId: 'c-1',
|
||||
kind: 'repeated_failures',
|
||||
consecutiveFailures: 3,
|
||||
errorMessage: 'Drive upload failed: 500',
|
||||
errorMessage: 'Något gick fel. Försök igen.',
|
||||
})
|
||||
)
|
||||
const [, , , , value] = mockSaveExtensionData.mock.calls[0]
|
||||
@@ -330,7 +330,7 @@ describe('cloud-backup auto-sync cron', () => {
|
||||
)
|
||||
const [, , , , value] = mockSaveExtensionData.mock.calls[0]
|
||||
expect((value as any).last_auto_sync_status).toBe('error')
|
||||
expect((value as any).last_auto_sync_error).toContain('Drive quota exceeded')
|
||||
expect((value as any).last_auto_sync_error).toBe('Något gick fel. Försök igen.')
|
||||
expect((value as any).consecutive_failures).toBe(3)
|
||||
})
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createClient } from '@supabase/supabase-js'
|
||||
import { NextResponse } from 'next/server'
|
||||
import { withCronContext } from '@/lib/api/with-cron-context'
|
||||
import { errorResponse, errorResponseFromCode } from '@/lib/errors/get-structured-error'
|
||||
import { getErrorMessage } from '@/lib/errors/get-error-message'
|
||||
import {
|
||||
performSync,
|
||||
CONNECTION_KEY,
|
||||
@@ -210,6 +211,7 @@ export const GET = withCronContext('cron.cloud_backup_auto_sync', async (_reques
|
||||
const consecutiveFailures = syncResult.ok
|
||||
? 0
|
||||
: (schedule.consecutive_failures ?? 0) + 1
|
||||
const safeSyncError = syncResult.ok ? null : getErrorMessage(syncResult.message)
|
||||
let lastAlertAt = schedule.last_alert_at ?? null
|
||||
if (!syncResult.ok) {
|
||||
lastAlertAt = await maybeAlert({
|
||||
@@ -217,7 +219,7 @@ export const GET = withCronContext('cron.cloud_backup_auto_sync', async (_reques
|
||||
userId,
|
||||
kind: syncResult.reason === 'needs_reauth' ? 'needs_reauth' : 'repeated_failures',
|
||||
consecutiveFailures,
|
||||
errorMessage: syncResult.message,
|
||||
errorMessage: safeSyncError,
|
||||
lastAlertAt,
|
||||
})
|
||||
}
|
||||
@@ -226,7 +228,7 @@ export const GET = withCronContext('cron.cloud_backup_auto_sync', async (_reques
|
||||
...schedule,
|
||||
last_auto_sync_at: new Date().toISOString(),
|
||||
last_auto_sync_status: syncResult.ok ? 'success' : 'error',
|
||||
last_auto_sync_error: syncResult.ok ? null : syncResult.message,
|
||||
last_auto_sync_error: safeSyncError,
|
||||
consecutive_failures: consecutiveFailures,
|
||||
last_alert_at: lastAlertAt,
|
||||
}
|
||||
@@ -235,10 +237,10 @@ export const GET = withCronContext('cron.cloud_backup_auto_sync', async (_reques
|
||||
results.push({
|
||||
companyId,
|
||||
status: syncResult.ok ? 'success' : 'error',
|
||||
error: syncResult.ok ? undefined : syncResult.message,
|
||||
error: safeSyncError ?? undefined,
|
||||
})
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : 'Unknown error'
|
||||
const safeMessage = getErrorMessage(err)
|
||||
ctx.log.error('cloud backup sync failed for company', err as Error, {
|
||||
companyId,
|
||||
})
|
||||
@@ -249,7 +251,7 @@ export const GET = withCronContext('cron.cloud_backup_auto_sync', async (_reques
|
||||
userId,
|
||||
kind: 'repeated_failures',
|
||||
consecutiveFailures,
|
||||
errorMessage: message.slice(0, 200),
|
||||
errorMessage: safeMessage.slice(0, 200),
|
||||
lastAlertAt: schedule.last_alert_at,
|
||||
})
|
||||
|
||||
@@ -257,7 +259,7 @@ export const GET = withCronContext('cron.cloud_backup_auto_sync', async (_reques
|
||||
...schedule,
|
||||
last_auto_sync_at: new Date().toISOString(),
|
||||
last_auto_sync_status: 'error',
|
||||
last_auto_sync_error: message.slice(0, 200),
|
||||
last_auto_sync_error: safeMessage.slice(0, 200),
|
||||
consecutive_failures: consecutiveFailures,
|
||||
last_alert_at: lastAlertAt,
|
||||
}
|
||||
@@ -267,7 +269,7 @@ export const GET = withCronContext('cron.cloud_backup_auto_sync', async (_reques
|
||||
},
|
||||
)
|
||||
|
||||
results.push({ companyId, status: 'error', error: message })
|
||||
results.push({ companyId, status: 'error', error: safeMessage })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user