refactor: replace fmt.Errorf and errors.New with coreerr.E from go-log
Replace all remaining fmt.Errorf and errors.New calls in production code with structured coreerr.E(op, msg, err) from forge.lthn.ai/core/go-log. Covers 10 files across the infra package and cmd/prod and cmd/monitor. Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
6beb06686a
commit
9a24df3d5f
10 changed files with 55 additions and 50 deletions
24
client.go
24
client.go
|
|
@ -10,6 +10,8 @@ import (
|
|||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
// RetryConfig controls exponential backoff retry behaviour.
|
||||
|
|
@ -105,7 +107,7 @@ func (a *APIClient) Do(req *http.Request, result any) error {
|
|||
|
||||
resp, err := a.client.Do(req)
|
||||
if err != nil {
|
||||
lastErr = fmt.Errorf("%s: %w", a.prefix, err)
|
||||
lastErr = coreerr.E(a.prefix, "request failed", err)
|
||||
if attempt < attempts-1 {
|
||||
a.backoff(attempt, req)
|
||||
}
|
||||
|
|
@ -115,7 +117,7 @@ func (a *APIClient) Do(req *http.Request, result any) error {
|
|||
data, err := io.ReadAll(resp.Body)
|
||||
_ = resp.Body.Close()
|
||||
if err != nil {
|
||||
lastErr = fmt.Errorf("read response: %w", err)
|
||||
lastErr = coreerr.E("client.Do", "read response", err)
|
||||
if attempt < attempts-1 {
|
||||
a.backoff(attempt, req)
|
||||
}
|
||||
|
|
@ -129,7 +131,7 @@ func (a *APIClient) Do(req *http.Request, result any) error {
|
|||
a.blockedUntil = time.Now().Add(retryAfter)
|
||||
a.mu.Unlock()
|
||||
|
||||
lastErr = fmt.Errorf("%s %d: rate limited", a.prefix, resp.StatusCode)
|
||||
lastErr = coreerr.E(a.prefix, fmt.Sprintf("rate limited: HTTP %d", resp.StatusCode), nil)
|
||||
if attempt < attempts-1 {
|
||||
select {
|
||||
case <-req.Context().Done():
|
||||
|
|
@ -142,7 +144,7 @@ func (a *APIClient) Do(req *http.Request, result any) error {
|
|||
|
||||
// Server errors are retryable.
|
||||
if resp.StatusCode >= 500 {
|
||||
lastErr = fmt.Errorf("%s %d: %s", a.prefix, resp.StatusCode, string(data))
|
||||
lastErr = coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, string(data)), nil)
|
||||
if attempt < attempts-1 {
|
||||
a.backoff(attempt, req)
|
||||
}
|
||||
|
|
@ -151,13 +153,13 @@ func (a *APIClient) Do(req *http.Request, result any) error {
|
|||
|
||||
// Client errors (4xx, except 429 handled above) are not retried.
|
||||
if resp.StatusCode >= 400 {
|
||||
return fmt.Errorf("%s %d: %s", a.prefix, resp.StatusCode, string(data))
|
||||
return coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, string(data)), nil)
|
||||
}
|
||||
|
||||
// Success — decode if requested.
|
||||
if result != nil {
|
||||
if err := json.Unmarshal(data, result); err != nil {
|
||||
return fmt.Errorf("decode response: %w", err)
|
||||
return coreerr.E("client.Do", "decode response", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -191,7 +193,7 @@ func (a *APIClient) DoRaw(req *http.Request) ([]byte, error) {
|
|||
|
||||
resp, err := a.client.Do(req)
|
||||
if err != nil {
|
||||
lastErr = fmt.Errorf("%s: %w", a.prefix, err)
|
||||
lastErr = coreerr.E(a.prefix, "request failed", err)
|
||||
if attempt < attempts-1 {
|
||||
a.backoff(attempt, req)
|
||||
}
|
||||
|
|
@ -201,7 +203,7 @@ func (a *APIClient) DoRaw(req *http.Request) ([]byte, error) {
|
|||
data, err := io.ReadAll(resp.Body)
|
||||
_ = resp.Body.Close()
|
||||
if err != nil {
|
||||
lastErr = fmt.Errorf("read response: %w", err)
|
||||
lastErr = coreerr.E("client.DoRaw", "read response", err)
|
||||
if attempt < attempts-1 {
|
||||
a.backoff(attempt, req)
|
||||
}
|
||||
|
|
@ -214,7 +216,7 @@ func (a *APIClient) DoRaw(req *http.Request) ([]byte, error) {
|
|||
a.blockedUntil = time.Now().Add(retryAfter)
|
||||
a.mu.Unlock()
|
||||
|
||||
lastErr = fmt.Errorf("%s %d: rate limited", a.prefix, resp.StatusCode)
|
||||
lastErr = coreerr.E(a.prefix, fmt.Sprintf("rate limited: HTTP %d", resp.StatusCode), nil)
|
||||
if attempt < attempts-1 {
|
||||
select {
|
||||
case <-req.Context().Done():
|
||||
|
|
@ -226,7 +228,7 @@ func (a *APIClient) DoRaw(req *http.Request) ([]byte, error) {
|
|||
}
|
||||
|
||||
if resp.StatusCode >= 500 {
|
||||
lastErr = fmt.Errorf("%s %d: %s", a.prefix, resp.StatusCode, string(data))
|
||||
lastErr = coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, string(data)), nil)
|
||||
if attempt < attempts-1 {
|
||||
a.backoff(attempt, req)
|
||||
}
|
||||
|
|
@ -234,7 +236,7 @@ func (a *APIClient) DoRaw(req *http.Request) ([]byte, error) {
|
|||
}
|
||||
|
||||
if resp.StatusCode >= 400 {
|
||||
return nil, fmt.Errorf("%s %d: %s", a.prefix, resp.StatusCode, string(data))
|
||||
return nil, coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, string(data)), nil)
|
||||
}
|
||||
|
||||
return data, nil
|
||||
|
|
|
|||
23
cloudns.go
23
cloudns.go
|
|
@ -3,10 +3,11 @@ package infra
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
const cloudnsBaseURL = "https://api.cloudns.net"
|
||||
|
|
@ -81,7 +82,7 @@ func (c *CloudNSClient) ListRecords(ctx context.Context, domain string) (map[str
|
|||
|
||||
var records map[string]CloudNSRecord
|
||||
if err := json.Unmarshal(data, &records); err != nil {
|
||||
return nil, fmt.Errorf("parse records: %w", err)
|
||||
return nil, coreerr.E("CloudNSClient.ListRecords", "parse records", err)
|
||||
}
|
||||
return records, nil
|
||||
}
|
||||
|
|
@ -108,11 +109,11 @@ func (c *CloudNSClient) CreateRecord(ctx context.Context, domain, host, recordTy
|
|||
} `json:"data"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &result); err != nil {
|
||||
return "", fmt.Errorf("parse response: %w", err)
|
||||
return "", coreerr.E("CloudNSClient.CreateRecord", "parse response", err)
|
||||
}
|
||||
|
||||
if result.Status != "Success" {
|
||||
return "", fmt.Errorf("cloudns: %s", result.StatusDescription)
|
||||
return "", coreerr.E("CloudNSClient.CreateRecord", result.StatusDescription, nil)
|
||||
}
|
||||
|
||||
return strconv.Itoa(result.Data.ID), nil
|
||||
|
|
@ -138,11 +139,11 @@ func (c *CloudNSClient) UpdateRecord(ctx context.Context, domain, recordID, host
|
|||
StatusDescription string `json:"statusDescription"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &result); err != nil {
|
||||
return fmt.Errorf("parse response: %w", err)
|
||||
return coreerr.E("CloudNSClient.UpdateRecord", "parse response", err)
|
||||
}
|
||||
|
||||
if result.Status != "Success" {
|
||||
return fmt.Errorf("cloudns: %s", result.StatusDescription)
|
||||
return coreerr.E("CloudNSClient.UpdateRecord", result.StatusDescription, nil)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -164,11 +165,11 @@ func (c *CloudNSClient) DeleteRecord(ctx context.Context, domain, recordID strin
|
|||
StatusDescription string `json:"statusDescription"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &result); err != nil {
|
||||
return fmt.Errorf("parse response: %w", err)
|
||||
return coreerr.E("CloudNSClient.DeleteRecord", "parse response", err)
|
||||
}
|
||||
|
||||
if result.Status != "Success" {
|
||||
return fmt.Errorf("cloudns: %s", result.StatusDescription)
|
||||
return coreerr.E("CloudNSClient.DeleteRecord", result.StatusDescription, nil)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -179,7 +180,7 @@ func (c *CloudNSClient) DeleteRecord(ctx context.Context, domain, recordID strin
|
|||
func (c *CloudNSClient) EnsureRecord(ctx context.Context, domain, host, recordType, value string, ttl int) (bool, error) {
|
||||
records, err := c.ListRecords(ctx, domain)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("list records: %w", err)
|
||||
return false, coreerr.E("CloudNSClient.EnsureRecord", "list records", err)
|
||||
}
|
||||
|
||||
// Check if record already exists
|
||||
|
|
@ -190,7 +191,7 @@ func (c *CloudNSClient) EnsureRecord(ctx context.Context, domain, host, recordTy
|
|||
}
|
||||
// Update existing record
|
||||
if err := c.UpdateRecord(ctx, domain, id, host, recordType, value, ttl); err != nil {
|
||||
return false, fmt.Errorf("update record: %w", err)
|
||||
return false, coreerr.E("CloudNSClient.EnsureRecord", "update record", err)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
|
@ -198,7 +199,7 @@ func (c *CloudNSClient) EnsureRecord(ctx context.Context, domain, host, recordTy
|
|||
|
||||
// Create new record
|
||||
if _, err := c.CreateRecord(ctx, domain, host, recordType, value, ttl); err != nil {
|
||||
return false, fmt.Errorf("create record: %w", err)
|
||||
return false, coreerr.E("CloudNSClient.EnsureRecord", "create record", err)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -582,5 +582,5 @@ func parseGitHubRepo(url string) (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("could not parse GitHub repo from URL: %s", url)
|
||||
return "", log.E("monitor.parseGitHubRepo", "could not parse GitHub repo from URL: "+url, nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@ package prod
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
"forge.lthn.ai/core/go-infra"
|
||||
)
|
||||
|
||||
|
|
@ -56,7 +55,7 @@ func getDNSClient() (*infra.CloudNSClient, error) {
|
|||
authID := os.Getenv("CLOUDNS_AUTH_ID")
|
||||
authPass := os.Getenv("CLOUDNS_AUTH_PASSWORD")
|
||||
if authID == "" || authPass == "" {
|
||||
return nil, errors.New("CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD required")
|
||||
return nil, coreerr.E("prod.getDNSClient", "CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD required", nil)
|
||||
}
|
||||
return infra.NewCloudNSClient(authID, authPass), nil
|
||||
}
|
||||
|
|
@ -77,7 +76,7 @@ func runDNSList(cmd *cli.Command, args []string) error {
|
|||
|
||||
records, err := dns.ListRecords(ctx, zone)
|
||||
if err != nil {
|
||||
return fmt.Errorf("list records: %w", err)
|
||||
return coreerr.E("prod.runDNSList", "list records", err)
|
||||
}
|
||||
|
||||
cli.Print("%s DNS records for %s\n\n", cli.BoldStyle.Render("▶"), cli.TitleStyle.Render(zone))
|
||||
|
|
@ -114,7 +113,7 @@ func runDNSSet(cmd *cli.Command, args []string) error {
|
|||
|
||||
changed, err := dns.EnsureRecord(ctx, dnsZone, host, recordType, value, dnsTTL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("set record: %w", err)
|
||||
return coreerr.E("prod.runDNSSet", "set record", err)
|
||||
}
|
||||
|
||||
if changed {
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ package prod
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
"forge.lthn.ai/core/go-infra"
|
||||
)
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ func init() {
|
|||
func getHCloudClient() (*infra.HCloudClient, error) {
|
||||
token := os.Getenv("HCLOUD_TOKEN")
|
||||
if token == "" {
|
||||
return nil, errors.New("HCLOUD_TOKEN environment variable required")
|
||||
return nil, coreerr.E("prod.getHCloudClient", "HCLOUD_TOKEN environment variable required", nil)
|
||||
}
|
||||
return infra.NewHCloudClient(token), nil
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ func runLBStatus(cmd *cli.Command, args []string) error {
|
|||
|
||||
lbs, err := hc.ListLoadBalancers(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("list load balancers: %w", err)
|
||||
return coreerr.E("prod.runLBStatus", "list load balancers", err)
|
||||
}
|
||||
|
||||
if len(lbs) == 0 {
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@ package prod
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
"forge.lthn.ai/core/go-infra"
|
||||
)
|
||||
|
||||
|
|
@ -71,7 +70,7 @@ func runSetup(cmd *cli.Command, args []string) error {
|
|||
|
||||
if err := step.fn(ctx, cfg); err != nil {
|
||||
cli.Print(" %s %s: %s\n", cli.ErrorStyle.Render("✗"), step.name, err)
|
||||
return fmt.Errorf("step %s failed: %w", step.name, err)
|
||||
return coreerr.E("prod.setup", "step "+step.name+" failed", err)
|
||||
}
|
||||
|
||||
cli.Print(" %s %s complete\n", cli.SuccessStyle.Render("✓"), step.name)
|
||||
|
|
@ -90,7 +89,7 @@ func stepDiscover(ctx context.Context, cfg *infra.Config) error {
|
|||
hc := infra.NewHCloudClient(hcloudToken)
|
||||
servers, err := hc.ListServers(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("list HCloud servers: %w", err)
|
||||
return coreerr.E("prod.stepDiscover", "list HCloud servers", err)
|
||||
}
|
||||
|
||||
for _, s := range servers {
|
||||
|
|
@ -115,7 +114,7 @@ func stepDiscover(ctx context.Context, cfg *infra.Config) error {
|
|||
hr := infra.NewHRobotClient(robotUser, robotPass)
|
||||
servers, err := hr.ListServers(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("list Robot servers: %w", err)
|
||||
return coreerr.E("prod.stepDiscover", "list Robot servers", err)
|
||||
}
|
||||
|
||||
for _, s := range servers {
|
||||
|
|
@ -141,7 +140,7 @@ func stepDiscover(ctx context.Context, cfg *infra.Config) error {
|
|||
func stepLoadBalancer(ctx context.Context, cfg *infra.Config) error {
|
||||
hcloudToken := os.Getenv("HCLOUD_TOKEN")
|
||||
if hcloudToken == "" {
|
||||
return errors.New("HCLOUD_TOKEN required for load balancer management")
|
||||
return coreerr.E("prod.stepLoadBalancer", "HCLOUD_TOKEN required for load balancer management", nil)
|
||||
}
|
||||
|
||||
hc := infra.NewHCloudClient(hcloudToken)
|
||||
|
|
@ -149,7 +148,7 @@ func stepLoadBalancer(ctx context.Context, cfg *infra.Config) error {
|
|||
// Check if LB already exists
|
||||
lbs, err := hc.ListLoadBalancers(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("list load balancers: %w", err)
|
||||
return coreerr.E("prod.stepLoadBalancer", "list load balancers", err)
|
||||
}
|
||||
|
||||
for _, lb := range lbs {
|
||||
|
|
@ -176,7 +175,7 @@ func stepLoadBalancer(ctx context.Context, cfg *infra.Config) error {
|
|||
for _, b := range cfg.LoadBalancer.Backends {
|
||||
host, ok := cfg.Hosts[b.Host]
|
||||
if !ok {
|
||||
return fmt.Errorf("backend host '%s' not found in config", b.Host)
|
||||
return coreerr.E("prod.stepLoadBalancer", "backend host '"+b.Host+"' not found in config", nil)
|
||||
}
|
||||
targets = append(targets, infra.HCloudLBCreateTarget{
|
||||
Type: "ip",
|
||||
|
|
@ -224,7 +223,7 @@ func stepLoadBalancer(ctx context.Context, cfg *infra.Config) error {
|
|||
|
||||
lb, err := hc.CreateLoadBalancer(ctx, req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create load balancer: %w", err)
|
||||
return coreerr.E("prod.stepLoadBalancer", "create load balancer", err)
|
||||
}
|
||||
|
||||
cli.Print(" Created: %s (ID: %d, IP: %s)\n",
|
||||
|
|
@ -237,7 +236,7 @@ func stepDNS(ctx context.Context, cfg *infra.Config) error {
|
|||
authID := os.Getenv("CLOUDNS_AUTH_ID")
|
||||
authPass := os.Getenv("CLOUDNS_AUTH_PASSWORD")
|
||||
if authID == "" || authPass == "" {
|
||||
return errors.New("CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD required")
|
||||
return coreerr.E("prod.stepDNS", "CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD required", nil)
|
||||
}
|
||||
|
||||
dns := infra.NewCloudNSClient(authID, authPass)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"syscall"
|
||||
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
var sshCmd = &cli.Command{
|
||||
|
|
@ -37,7 +38,7 @@ func runSSH(cmd *cli.Command, args []string) error {
|
|||
for n, h := range cfg.Hosts {
|
||||
cli.Print(" %s %s (%s)\n", cli.BoldStyle.Render(n), h.IP, h.Role)
|
||||
}
|
||||
return fmt.Errorf("host '%s' not found in infra.yaml", name)
|
||||
return coreerr.E("prod.ssh", "host '"+name+"' not found in infra.yaml", nil)
|
||||
}
|
||||
|
||||
sshArgs := []string{
|
||||
|
|
@ -55,7 +56,7 @@ func runSSH(cmd *cli.Command, args []string) error {
|
|||
|
||||
sshPath, err := exec.LookPath("ssh")
|
||||
if err != nil {
|
||||
return fmt.Errorf("ssh not found: %w", err)
|
||||
return coreerr.E("prod.ssh", "ssh not found", err)
|
||||
}
|
||||
|
||||
// Replace current process with SSH
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"forge.lthn.ai/core/go-ansible"
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
"forge.lthn.ai/core/go-infra"
|
||||
)
|
||||
|
||||
|
|
@ -114,14 +115,14 @@ func checkHost(ctx context.Context, name string, host *infra.Host) hostStatus {
|
|||
|
||||
client, err := ansible.NewSSHClient(sshCfg)
|
||||
if err != nil {
|
||||
s.Error = fmt.Errorf("create SSH client: %w", err)
|
||||
s.Error = coreerr.E("prod.checkHost", "create SSH client", err)
|
||||
return s
|
||||
}
|
||||
defer func() { _ = client.Close() }()
|
||||
|
||||
start := time.Now()
|
||||
if err := client.Connect(ctx); err != nil {
|
||||
s.Error = fmt.Errorf("SSH connect: %w", err)
|
||||
s.Error = coreerr.E("prod.checkHost", "SSH connect", err)
|
||||
return s
|
||||
}
|
||||
s.Connected = true
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
package infra
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
coreio "forge.lthn.ai/core/go-io"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
|
@ -232,12 +232,12 @@ type BackupJob struct {
|
|||
func Load(path string) (*Config, error) {
|
||||
data, err := coreio.Local.Read(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read infra config: %w", err)
|
||||
return nil, coreerr.E("infra.Load", "read infra config", err)
|
||||
}
|
||||
|
||||
var cfg Config
|
||||
if err := yaml.Unmarshal([]byte(data), &cfg); err != nil {
|
||||
return nil, fmt.Errorf("parse infra config: %w", err)
|
||||
return nil, coreerr.E("infra.Load", "parse infra config", err)
|
||||
}
|
||||
|
||||
// Expand SSH key paths
|
||||
|
|
@ -269,7 +269,7 @@ func Discover(startDir string) (*Config, string, error) {
|
|||
}
|
||||
dir = parent
|
||||
}
|
||||
return nil, "", fmt.Errorf("infra.yaml not found (searched from %s)", startDir)
|
||||
return nil, "", coreerr.E("infra.Discover", "infra.yaml not found (searched from "+startDir+")", nil)
|
||||
}
|
||||
|
||||
// HostsByRole returns all hosts matching the given role.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -210,7 +212,7 @@ func (c *HCloudClient) GetLoadBalancer(ctx context.Context, id int) (*HCloudLoad
|
|||
func (c *HCloudClient) CreateLoadBalancer(ctx context.Context, req HCloudLBCreateRequest) (*HCloudLoadBalancer, error) {
|
||||
body, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal request: %w", err)
|
||||
return nil, coreerr.E("HCloudClient.CreateLoadBalancer", "marshal request", err)
|
||||
}
|
||||
|
||||
var result struct {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue