Webhook deletion commits a partial delete and reports success when a delete statement fails #262
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while auditing every
Begin/Commit/Rollbackpath for #256. Not fixed there: it is a different failure and out of that issue's scope.deleteWebhookResources(internal/handlers/source_management.go) opens a transaction and issues three deletes without checking any of them:A failing delete sets
.Erroron the returned session and leaves the transaction usable, so the code commits whatever did succeed. The operator is redirected to/sourcesas though the deletion worked, andh.dbMgr.DeleteDBthen hard-deletes the per-webhook event database anyway — its own error is logged and swallowed too. The outcome is a webhook whose entrypoints or targets survive in the main database while its entire event history is permanently gone, reported as a success.commitWebhook, twenty lines above in the same file, does check each statement and rolls back, so this reads as an oversight rather than a decision.Definition of done: check each delete, roll back and return a 500 on any failure, and do not delete the event database unless the configuration delete committed.
Plan:
commitWebhookDeletion, matchingcommitWebhook's idiom in the same file: check every statement,tx.Rollback()and return the error on any failure.deleteWebhookResourcesreturnsh.serverErroron that error and does not touch the event database, so a failed configuration delete loses nothing.DeleteDB. IfDeleteDBthen fails the webhook is gone and an unreferenced event database file is left on disk — reported to the operator withh.serverErrorrather than a success redirect, since a leftover file can be removed by hand while deleted history cannot be recovered.targetstable, which leaves the transaction usable exactly as a real database error does) must leave the webhook, entrypoint, target and event database file all intact and return 500; plus a positive control that a normal deletion still removes all four.Begin()sites.commitWebhookandcreateAndFanOut(internal/handlers/webhook.go) both check every statement and roll back; this was the only one that did not.Implemented in #273.
commitWebhookDeletionnow checks each of the three deletes and rolls back on any failure;deleteWebhookResourcesreports it withh.serverErrorand does not touch the event database. The configuration commit runs beforeDeleteDB, and aDeleteDBfailure is reported withh.serverErrorrather than the old success redirect, so the worst case is a leftover event database file the operator is told about instead of history destroyed behind a 303.Verified:
make checkgreen withGOFLAGS=-count=1, lint 0 issues. A new test injects a failure into thetargetsdelete (.Errorset, transaction still usable — the exact reported condition) and asserts a 500 with the webhook, entrypoint, target and event database file all intact; with only the handler reverted it fails on every one of those assertions, includingunable to find file .../events-<id>.db. A positive-control test covers normal deletion, and a running instance was driven through create-target-delete end to end: 303 to/sources, webhook delisted, detail 404, event database file gone.Audit: the repo has three
Begin()sites;commitWebhookandcreateAndFanOutboth check every statement, so this was the only one.