Skip to content

Commit 2f31ba9

Browse files
committed
feat: improve rollback error handling and tracking
Add comprehensive error collection during rollback operations to track partial failures. Update rollback success status based on whether any errors occurred. Return aggregated error message when rollback completes with errors. - Add rollbackErrors slice to collect errors from sysctl, file, and qdisc restoration - Check and handle LoadFromFile error that was previously ignored - Update RecordRollback to reflect actual success status based on error
1 parent 0e5ff07 commit 2f31ba9

2 files changed

Lines changed: 20 additions & 3 deletions

File tree

internal/server/service/apply.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,13 @@ func (s *ApplyService) rollbackInternal(snapshotID string) error {
172172
return err
173173
}
174174

175+
var rollbackErrors []string
176+
175177
// Restore sysctl values
176178
if snapshot.State.Sysctl != nil {
177179
if err := s.adapter.Sysctl.SetMultiple(snapshot.State.Sysctl); err != nil {
178180
s.logger.Error("failed to restore sysctl", zap.Error(err))
181+
rollbackErrors = append(rollbackErrors, fmt.Sprintf("restore sysctl failed: %v", err))
179182
}
180183
}
181184

@@ -185,13 +188,19 @@ func (s *ApplyService) rollbackInternal(snapshotID string) error {
185188
s.logger.Error("failed to restore file",
186189
zap.String("path", path),
187190
zap.Error(err))
191+
rollbackErrors = append(rollbackErrors, fmt.Sprintf("restore file %s failed: %v", path, err))
188192
}
189193
}
190194

191195
// Reload sysctl from restored file
192196
sysctlFile := "/etc/sysctl.d/99-nettune.conf"
193197
if _, ok := snapshot.Backups[sysctlFile]; ok {
194-
s.adapter.Sysctl.LoadFromFile(sysctlFile)
198+
if err := s.adapter.Sysctl.LoadFromFile(sysctlFile); err != nil {
199+
s.logger.Error("failed to reload sysctl from restored file",
200+
zap.String("path", sysctlFile),
201+
zap.Error(err))
202+
rollbackErrors = append(rollbackErrors, fmt.Sprintf("reload sysctl file %s failed: %v", sysctlFile, err))
203+
}
195204
}
196205

197206
// Restore qdisc
@@ -201,12 +210,20 @@ func (s *ApplyService) rollbackInternal(snapshotID string) error {
201210
s.logger.Error("failed to restore qdisc",
202211
zap.String("interface", iface),
203212
zap.Error(err))
213+
rollbackErrors = append(rollbackErrors, fmt.Sprintf("restore qdisc for %s failed: %v", iface, err))
204214
}
205215
}
206216
}
207217

208218
if s.historyService != nil {
209-
s.historyService.RecordRollback(snapshotID, true)
219+
s.historyService.RecordRollback(snapshotID, len(rollbackErrors) == 0)
220+
}
221+
222+
if len(rollbackErrors) > 0 {
223+
s.logger.Error("rollback completed with errors",
224+
zap.String("snapshot", snapshotID),
225+
zap.Strings("errors", rollbackErrors))
226+
return fmt.Errorf("%w: %s", types.ErrRollbackFailed, strings.Join(rollbackErrors, "; "))
210227
}
211228

212229
s.logger.Info("rolled back to snapshot", zap.String("snapshot", snapshotID))

js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jtsang/nettune-mcp",
3-
"version": "0.2.2",
3+
"version": "0.2.3",
44
"private": false,
55
"description": "MCP stdio wrapper for nettune - TCP network optimization tool",
66
"type": "module",

0 commit comments

Comments
 (0)