mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-09-12 19:51:00 +05:00
fix(dns): report an OVH zone refresh failure for what it is
refreshZone runs after the record write has already succeeded, so a failure there means the change exists at the provider but is not being served yet. It was left unguarded at all six call sites, so the caller saw a bare transport error and would reasonably read it as "nothing was applied" — while a type change had already deleted the old record and created its replacement. Rolling the write back would destroy correct state over a publish failure, and re-deleting after an uncertain network error is how records get lost. The error now says what actually happened and how it resolves: the next successful change to the zone publishes it, or the user can refresh the zone from the OVH manager. Guarding the helper covers upsertRecord and deleteRecord too, not just the type change Greptile pointed at. Reported by Greptile on #5258. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7ae566f4de
commit
28f71e727a
@ -440,6 +440,33 @@ describe("ovhClient.updateRecord", () => {
|
||||
/Recreate it manually: A app\.example\.com -> 1\.1\.1\.1/,
|
||||
);
|
||||
});
|
||||
|
||||
it("says the change was applied when only the zone refresh fails", async () => {
|
||||
const cfg = freshConfig();
|
||||
mockApi(
|
||||
ovhSuccess({
|
||||
id: 4,
|
||||
zone: "example.com",
|
||||
fieldType: "A",
|
||||
subDomain: "app",
|
||||
target: "1.1.1.1",
|
||||
ttl: 60,
|
||||
}),
|
||||
ovhSuccess(null),
|
||||
ovhSuccess({ id: 11 }),
|
||||
ovhError("Service unavailable", 503),
|
||||
);
|
||||
|
||||
// The replacement succeeded, so the record exists at the provider — only
|
||||
// publishing failed. Rolling back would destroy correct state.
|
||||
await expect(
|
||||
ovhClient.updateRecord(cfg, "example.com", "4", {
|
||||
type: "CNAME",
|
||||
name: "app.example.com",
|
||||
content: "example.com",
|
||||
}),
|
||||
).rejects.toThrow(/was applied, but refreshing zone "example\.com" failed/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("ovhClient.deleteRecord", () => {
|
||||
|
||||
@ -164,11 +164,23 @@ const mapWithConcurrency = async <T, R>(
|
||||
return results;
|
||||
};
|
||||
|
||||
// OVH only applies zone changes once the zone is explicitly refreshed.
|
||||
// OVH only applies zone changes once the zone is explicitly refreshed. This runs
|
||||
// after the record write has already succeeded, so a failure here means the
|
||||
// change exists at the provider but is not being served yet. Rolling the write
|
||||
// back would destroy correct state over a publish failure, so say what actually
|
||||
// happened instead of letting the caller read it as "nothing was applied".
|
||||
const refreshZone = async (config: OvhConfig, zone: string) => {
|
||||
await ovhFetch(config, `/domain/zone/${encodeURIComponent(zone)}/refresh`, {
|
||||
method: "POST",
|
||||
});
|
||||
try {
|
||||
await ovhFetch(config, `/domain/zone/${encodeURIComponent(zone)}/refresh`, {
|
||||
method: "POST",
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`OVH: the record change was applied, but refreshing zone "${zone}" failed, so it is not served yet. The next successful change to this zone will publish it, or you can refresh the zone from the OVH manager. Cause: ${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
}`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Used to undo the delete half of a type change when the replacement fails.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user