go-ollama/errors.go
2026-06-11 20:01:48 +02:00

91 lines
1.7 KiB
Go

package gollama
import (
"errors"
"fmt"
"net"
"strings"
"github.com/ollama/ollama/api"
)
// Error wraps Ollama API and transport failures with operation context.
type Error struct {
Op string
Model string
Status int
Message string
Err error
}
func (e *Error) Error() string {
var b strings.Builder
if e.Op != "" {
b.WriteString(e.Op)
b.WriteString(": ")
}
if e.Model != "" {
b.WriteString(e.Model)
b.WriteString(": ")
}
if e.Message != "" {
b.WriteString(e.Message)
} else if e.Err != nil {
b.WriteString(e.Err.Error())
}
return b.String()
}
func (e *Error) Unwrap() error { return e.Err }
func wrapError(op, model string, err error) error {
if err == nil {
return nil
}
var e *Error
if errors.As(err, &e) {
return err
}
out := &Error{Op: op, Model: model, Err: err}
var status api.StatusError
if errors.As(err, &status) {
out.Status = status.StatusCode
out.Message = status.Error()
}
return out
}
// IsNotFound reports whether err is a 404 from the Ollama API.
func IsNotFound(err error) bool {
var status api.StatusError
if errors.As(err, &status) {
return status.StatusCode == 404
}
var e *Error
if errors.As(err, &e) {
return e.Status == 404
}
return false
}
// IsConnection reports whether err is a network connectivity failure.
func IsConnection(err error) bool {
var netErr net.Error
if errors.As(err, &netErr) {
return true
}
var opErr *net.OpError
if errors.As(err, &opErr) {
return true
}
msg := err.Error()
return strings.Contains(msg, "connection refused") ||
strings.Contains(msg, "no such host") ||
strings.Contains(msg, "i/o timeout")
}
func errNoModel() error {
return fmt.Errorf("model name is required (set default model on client or pass WithModel)")
}