Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: improve exception handling in AlertScheduleProvider and MigrateD…
…atabaseV2

AlertScheduleProvider: skip unparseable schedules instead of adding them
to cache as broken objects. A partially-constructed AlertSchedule with no
parsed working hours has unpredictable IsWorkingTime behavior - skipping
is safer than a fallback that silently misfires alerts.

TreeValuesCache.MigrateDatabaseV2: add success/failed counters and log
migration summary so data loss during migration is visible in logs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
  • Loading branch information
lotgon and claude committed Mar 23, 2026
commit 3e1c6b6fef622f096ff2518af1480e223b527791
10 changes: 2 additions & 8 deletions src/server/HSMServer.Core/AlertSchedule/AlertScheduleProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,8 @@ private void LoadSchedulesFromDatabase()
}
catch (Exception ex)
{
_logger.Error(ex, $"Failed to parse alert schedule. Id = {entity.Id}, Name = {entity.Name}. Using raw entity as fallback.");
schedule = new AlertSchedule()
{
Id = new Guid(entity.Id),
Name = entity.Name,
Timezone = entity.Timezone,
Schedule = entity.Schedule,
};
_logger.Error(ex, $"Failed to parse alert schedule. Id = {entity.Id}, Name = {entity.Name}. Schedule will be skipped.");
continue;
}

_cache[schedule.Id] = new CacheEntry
Expand Down
11 changes: 11 additions & 0 deletions src/server/HSMServer.Core/Cache/TreeValuesCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1836,6 +1836,9 @@ private void ApplySensors(List<SensorEntity> sensorEntities, Dictionary<string,

private void MigrateDatabseV2()
{
var success = 0;
var failed = 0;

foreach ((byte[] key, byte[] value) in _database.MigrateDatabaseV2())
{
var keyArr = Encoding.UTF8.GetString(key).Split("_");
Expand All @@ -1854,15 +1857,23 @@ private void MigrateDatabseV2()
catch (Exception ex)
{
_logger.Error(ex, $"Failed to deserialize sensor value during V2 migration. SensorId = {sensorId}");
failed++;
continue;
}

if (!policy.TimeIsUp(val.Time))
{
_database.AddSensorValue(sensorId, val);
}

success++;
}
}

if (failed > 0)
_logger.Warn($"V2 migration completed with errors: {success} records migrated, {failed} records skipped due to deserialization errors.");
else
_logger.Info($"V2 migration completed successfully: {success} records migrated.");
}

private void ApplyAccessKeys(List<AccessKeyEntity> entities)
Expand Down
Loading