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)") }