Skip to content
Fuse
Esc
navigateopen⌘Jpreview
On this page

Errors

APIError, error codes, and the Is* helpers

Every SDK method that talks to the orchestrator returns a Go error. Non-2xx responses come back as a *APIError, decoded from the server’s structured error envelope; anything else (a network failure, a body that fails to decode) is a plain wrapped error. Branch on the code, not the message:

env, err := client.Environments.Get(ctx, id)
if fuse.IsNotFound(err) {
	// handle the 404 case
} else if err != nil {
	log.Fatal(err)
}

fuse.AsAPIError(err) gets you the full struct when you need more than a yes/no check, Status, Code, RequestID (for correlating with server-side logs), and Body:

if apiErr, ok := fuse.AsAPIError(err); ok {
	log.Printf("status=%d code=%s request_id=%s", apiErr.Status, apiErr.Code, apiErr.RequestID)
}

Code-checking helpers

func IsNotFound(err error) bool
func IsConflict(err error) bool
func IsUnauthorized(err error) bool
func IsInvalidArgument(err error) bool
func IsUnavailable(err error) bool

Each reports whether err is an *APIError with the matching code. Prefer these over comparing Code strings directly, and definitely over comparing Error()’s formatted message, which is meant for logs, not branching logic.

The server returns further codes with no matching Is* helper: internal, route_not_found, and unimplemented (501, when a provider has no guest to Exec or Attach into). Check apiErr.Code against the constant directly until a helper is added.

APIError

type APIError struct {
	Status    int
	Code      string
	Message   string
	Details   map[string]string
	RequestID string
	Body      []byte
}

Full code list

Constant Wire value Typical status
CodeNotFound not_found 404
CodeRouteNotFound route_not_found 404
CodeConflict conflict 409
CodeInvalidArgument invalid_argument 400
CodePayloadTooLarge payload_too_large 413
CodeUnauthorized unauthorized 401 or 403
CodeUnavailable unavailable 503
CodeInternal internal 500 or 502
CodeUnimplemented unimplemented 501

route_not_found and not_found are both 404 but mean different things: route_not_found means the URL matches no route the server exposes (a wrong host, a wrong port, or a server that isn’t a fuse orchestrator at all), where not_found means the route exists and the resource doesn’t. The distinction matters in practice because the /v1/api-keys routes are registered only on a Postgres-backed orchestrator, so API keys calls against an orchestrator without DATABASE_URL come back as route_not_found.

CheckResponse

func CheckResponse(resp *http.Response) error

The lower-level function every service method calls internally: returns nil for a 2xx response, or a populated *APIError otherwise. You won’t normally call this directly, it’s exported because raw HTTP callers (like the CLI’s fuse metrics command) reuse it to get the same error mapping as every other SDK call.

Was this page helpful?