fix(api): distinguish domain-not-found (404) from provider failure (502) on zone endpoints
Introduce service.ErrProviderUnavailable, wrapped only around the provider GetRecords call in ZoneRecords. handleZoneRecords and handleTemplateFromZone now use errors.Is against it to tell a real provider outage (502) apart from local resolution failures such as an unknown domain (404), instead of collapsing every ZoneRecords error into a blanket 502. Also fixes handleTemplateFromZone's GetDomain error branch to return 404 "domain not found" instead of 500, for consistency with handleSetDomainTemplate/handleDomainHistory. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwxdSt4reTm7Dj1oxRvpP3
This commit is contained in:
@@ -2,6 +2,8 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -13,6 +15,13 @@ import (
|
||||
"github.com/vasyakrg/dns-autoresolver/internal/store/dto"
|
||||
)
|
||||
|
||||
// ErrProviderUnavailable marks failures that happened while talking to the
|
||||
// DNS provider itself (network, auth, rate limit, ...), as opposed to
|
||||
// failures resolving the domain/zone locally (not found, bad credentials
|
||||
// stored, unknown provider name). Callers use errors.Is against this to
|
||||
// pick 502 vs 404 without leaking provider error details as "not found".
|
||||
var ErrProviderUnavailable = errors.New("service: provider unavailable")
|
||||
|
||||
// DomainRef is the minimal data the service needs about a domain.
|
||||
type DomainRef struct {
|
||||
ZoneID string
|
||||
@@ -107,7 +116,14 @@ func (s *DomainService) ZoneRecords(ctx context.Context, projectID, domainID uui
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.GetRecords(ctx, provider.Credentials{Secret: string(secret)}, ref.ZoneID)
|
||||
recs, err := p.GetRecords(ctx, provider.Credentials{Secret: string(secret)}, ref.ZoneID)
|
||||
if err != nil {
|
||||
// Only a failure of the provider call itself is "provider unavailable" —
|
||||
// LoadZone/ByName/Decrypt errors above are local resolution failures
|
||||
// (e.g. domain not found) and must not be conflated with it.
|
||||
return nil, fmt.Errorf("%w: %v", ErrProviderUnavailable, err)
|
||||
}
|
||||
return recs, nil
|
||||
}
|
||||
|
||||
// Apply applies updates always (when ApplyUpdates) and prunes only when ApplyPrunes.
|
||||
|
||||
Reference in New Issue
Block a user