Publisert - 12.05.2026

Error Handling

Overview

Errors can occur at two points in the system: during upstream sync and during client requests. Each is handled differently.

Upstream Sync Errors

Upstream API Failures

If any of the three upstream API calls fail (non-2xx status code), HttpRequestException is thrown and the entire sync aborts.

What happens:

  • No version increment occurs.
  • No data is written to MongoDB.
  • The exception propagates to ASP.NET Core's default exception handler, which returns 500 Internal Server Error. In Development mode, the response includes a developer exception page (HTML). In Production mode, the response body is empty.
  • Existing data in MongoDB remains untouched — clients continue to receive the last successfully synced data.

Recovery: The Kubernetes CronJob has backoffLimit: 3, so it will retry automatically. If retries are exhausted, the job is marked as failed and can be investigated via kubectl get jobs.

Partial Sync Failures

If upstream fetches succeed but a MongoDB write fails mid-sync:

  • The version counter has already been incremented.
  • Some raw FHIR or output records may have been upserted with the new version number.
  • Soft-deletes may not have been applied.
  • The SyncHistoryEntry for this run will not have been written, so the run is missing from SyncHistory.

Impact: Clients using ?sinceVersion=N may see some but not all changes from this sync run.

Recovery: Trigger a new sync. The next sync is idempotent — content-hash change detection means already-correct records are left alone, while inconsistent records are reconciled. No manual intervention is needed.

Timeout

The sync endpoint has no explicit timeout configured. The Kubernetes CronJob should set an activeDeadlineSeconds to prevent runaway syncs:

jobTemplate:
  spec:
    activeDeadlineSeconds: 300  # Kill after 5 minutes

Client Request Errors

Authentication Errors

Scenario Response
Missing X-API-KEY header 401 Unauthorized with { "error": "Invalid or missing API key." }
Invalid API key 401 Unauthorized with { "error": "Invalid or missing API key." }

The error message is intentionally identical for both cases to avoid leaking information about valid keys.

Invalid sinceVersion

Scenario Response
?sinceVersion=abc (non-numeric) 400 Bad Request (ASP.NET model binding error)
?sinceVersion=-1 (negative) 200 OK with all versioned items (treated as "everything since before the beginning")
?sinceVersion=999999 (future) 200 OK with empty items list and current version

MongoDB Connection Failures

If MongoDB is unreachable when a client makes a request:

  • The controller throws an unhandled MongoConnectionException.
  • ASP.NET Core returns 500 Internal Server Error.
  • The error is logged at Error level.

Monitoring: Watch for 500 responses on the output endpoints. MongoDB connection issues typically resolve once the database is reachable again — no data loss occurs.

Logging

The sync service logs at Information level. Unhandled exceptions (upstream failures, MongoDB errors) are logged by the ASP.NET Core infrastructure.

Level What
Information Sync started, sync completed with stats
Error Unhandled exceptions (logged automatically by ASP.NET Core)

Key Log Messages

# Sync lifecycle (SyncService)
"Starting sync"
"Sync completed in {Duration}ms: {Added} added, {Updated} updated, {Unchanged} unchanged, {Deleted} deleted (version {Version})"

Note: Items without identifiers are silently filtered out during conversion (no log message is emitted). Consider adding explicit logging for skipped items if observability is important.

For per-collection detail, query the SyncHistory collection — every sync run writes one entry there with full statistics and business keys for added/updated/deleted records.

Structured Logging

All log messages use structured logging with named parameters, making them queryable in log aggregation tools (e.g., Seq, Elasticsearch, Application Insights).

Monitoring Recommendations

What to monitor Alert condition
Sync CronJob status Job failed after all retries
Sync duration Duration > 60 seconds (indicates upstream slowness)
Sync result counts deleted count unusually high (possible upstream issue)
API 401 responses Spike in unauthorized requests (possible key leak or misconfiguration)
API 500 responses Any 500 response (MongoDB or unexpected error)
Data freshness SyncMetadata.LastSyncAt older than 36 hours
Sync history gap Most recent SyncHistory entry's SyncedAt older than 36 hours, or Version lags behind SyncMetadata.CurrentVersion (indicates partial sync failure)

Failure Modes Summary

Failure Data impact Auto-recovery
Upstream API down None (old data served) Yes, next sync
Upstream returns empty data All records soft-deleted Yes, next sync restores if data returns
MongoDB down during sync Partial writes possible Yes, next sync overwrites
MongoDB down during client request 500 error, no data Yes, when MongoDB recovers
Invalid upstream data (missing IDs) Items silently skipped No — check upstream data quality

Søk i Utviklerportalen

Søket er fullført!