Files
2026-08-28 12:21:44 +05:30

67 lines
2.5 KiB
Go

package knowledge
import "fmt"
// Structured errors, per §10: a code, never a bare string, and user-facing text
// derived at the surface rather than raised from here.
//
// The codes matter more than they look. "the embedding provider is down" and
// "this deployment has no embedding credential" are the same sentence to a
// user and completely different to an operator — one is a page, the other is a
// configuration task nobody has done. Flattening them into a single failure
// makes that distinction unanswerable from a log.
type Error struct {
Code string `json:"code"`
Message string `json:"message"`
Cause error `json:"-"`
}
func (e *Error) Error() string {
if e.Cause != nil {
return fmt.Sprintf("%s: %s: %v", e.Code, e.Message, e.Cause)
}
return fmt.Sprintf("%s: %s", e.Code, e.Message)
}
func (e *Error) Unwrap() error { return e.Cause }
const (
// ErrNoPrincipal is retrieval called without a caller. §5: there is no
// overload without a principal, and this is what enforces it at run time
// for a caller that assembled the struct by hand.
ErrNoPrincipal = "knowledge.no_principal"
// ErrNoSources is retrieval called without naming a corpus. An agent reads
// the sources its spec declares; an empty list is not "all of them".
ErrNoSources = "knowledge.no_sources"
// ErrNoAudience is an ingest whose document reaches nobody. §5.
ErrNoAudience = "knowledge.no_audience"
// ErrNotConfigured is a missing embedding credential, or the stand-in
// embedder refusing to run in production.
ErrNotConfigured = "knowledge.not_configured"
// ErrEmbedUnavailable is a provider that is reachable-in-principle and
// failing now: a timeout, a 429, a 503. Retryable.
ErrEmbedUnavailable = "knowledge.embed_unavailable"
// ErrEmbedFailed is a provider answering something this code cannot use.
// Not retryable — the same request will fail the same way.
ErrEmbedFailed = "knowledge.embed_failed"
// ErrModelMismatch is a corpus embedded with one model being searched with
// another. Refused rather than served: vectors from two models are not
// comparable, and the failure mode is confident nonsense.
ErrModelMismatch = "knowledge.model_mismatch"
// ErrIngestFailed and ErrRetrieveFailed are the database saying no.
ErrIngestFailed = "knowledge.ingest_failed"
ErrRetrieveFailed = "knowledge.retrieve_failed"
)
// Retryable reports whether the same call might succeed later.
func (e *Error) Retryable() bool {
return e.Code == ErrEmbedUnavailable
}