kernel

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package kernel is what every layer may use: lenient reads of Dify's JSON (Object), because its types drift between versions, and the errors a call can end in.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrAuthentication = errors.New("dify: authentication failed")
	ErrRateLimited    = errors.New("dify: rate limited")
	ErrValidation     = errors.New("dify: validation failed")
	ErrFileUpload     = errors.New("dify: file upload rejected")
	ErrNotFound       = errors.New("dify: not found")
	ErrTimeout        = errors.New("dify: request timed out")
	ErrNetwork        = errors.New("dify: network error")
)

Sentinels to test an error against with errors.Is. They classify what went wrong without committing a caller to a concrete type:

errors.Is(err, dify.ErrAuthentication)   401 — the key is wrong or revoked
errors.Is(err, dify.ErrRateLimited)      429 — see APIError.RetryAfter
errors.Is(err, dify.ErrValidation)       422, or arguments refused before sending
errors.Is(err, dify.ErrFileUpload)       an upload Dify would not take
errors.Is(err, dify.ErrNotFound)         404
errors.Is(err, dify.ErrTimeout)          the request ran past its deadline
errors.Is(err, dify.ErrNetwork)          the connection failed

errors.As(err, &apiErr) reaches the *APIError itself, which carries the server's message, code and version.

Functions

func ArgError

func ArgError(format string, args ...any) error

func AsFloat

func AsFloat(v any) (float64, bool)

func AsString

func AsString(v any) string

func FirstNonZero

func FirstNonZero[T comparable](a, b T) T

func IsIdempotent

func IsIdempotent(method string) bool

IsIdempotent reports whether repeating a request has the same effect as making it once, so a retry after it was sent cannot duplicate anything.

func MarkUpload

func MarkUpload(e *APIError, upload bool)

func MaskSecret

func MaskSecret(value string) string

MaskSecret renders a key the way it is safe to print: app-****3f2a.

Dify issues keys with a type prefix (app-, dataset-), which is kept so a masked key is still identifiable.

func OrEmpty

func OrEmpty(m map[string]any) map[string]any

OrEmpty keeps an inputs map from being sent as null, which Dify's payload models reject where they want an object.

func SleepCtx

func SleepCtx(ctx context.Context, d time.Duration) error

SleepCtx waits, or stops waiting when the context ends. In the kernel because both the transport's backoff and a document's indexing poll wait this way.

func Truthy

func Truthy(v any) bool

Truthy mirrors how Dify's own code tests a value: a non-empty string is true even when it spells zero, a number is true when it is not zero.

Types

type APIError

type APIError struct {
	// StatusCode is the HTTP status. Zero for an error Dify reported inside a
	// stream after the 200 had already gone out.
	StatusCode int
	// Code is Dify's machine-readable error code, e.g. "app_unavailable".
	Code string
	// Message is what went wrong, without the server it went wrong on.
	Message string
	// Body is the decoded error body, when it was JSON.
	Body map[string]any
	// ServerVersion is the version of the Dify that answered, from X-Version.
	ServerVersion string
	// ServerEnv is PRODUCTION or TESTING, from X-Env.
	ServerEnv string
	// TraceID is Dify's own id for this request, when it is tracing.
	TraceID string
	// RetryAfter is the server's hint on a 429. Zero when it gave none.
	RetryAfter time.Duration
	// InStream is true when Dify reported this as an event mid-stream. An HTTP
	// 200 is not a successful run: a failure after the status line arrives as
	// an "error" event.
	InStream bool
	// contains filtered or unexported fields
}

APIError is Dify answering, and the answer being an error.

It carries which Dify answered. Every response Dify sends — errors included — has X-Version and X-Env on it, and the first question about a failing call is always which server and which version. By the time someone asks, the error message is usually all that is left, so the version goes in it.

func (*APIError) Error

func (e *APIError) Error() string

func (*APIError) Is

func (e *APIError) Is(target error) bool

Is lets errors.Is classify an APIError by status without a type switch.

type ArgumentError

type ArgumentError struct {
	Message string
}

ArgumentError is a call this client refused before spending a request on it. It matches ErrValidation, the same as a 422 from Dify, because to the caller both mean "these arguments will not do".

func (*ArgumentError) Error

func (e *ArgumentError) Error() string

func (*ArgumentError) Is

func (e *ArgumentError) Is(target error) bool

type Object

type Object map[string]any

Object is a decoded JSON object, read leniently.

Dify's answers drift: a count arrives as a string on one route (binding_count on a tag), a timestamp as a float on another, a field goes missing on an older server. Decoding straight into tagged structs turns each of those into a failed call. Reading through these accessors turns them into a zero value instead, and every typed result keeps the whole answer on Raw so nothing is lost either way.

func (Object) Bool

func (o Object) Bool(key string) bool

func (Object) Float

func (o Object) Float(key string) float64

func (Object) Has

func (o Object) Has(key string) bool

func (Object) Int

func (o Object) Int(key string) int

func (Object) Int64

func (o Object) Int64(key string) int64

func (Object) IntPtr

func (o Object) IntPtr(key string) *int64

IntPtr distinguishes absent from zero, for fields where the difference is information — a timestamp that was never set is not the epoch.

func (Object) List

func (o Object) List(key string) []any

func (Object) Maps

func (o Object) Maps(key string) []map[string]any

Maps is objs with the plain map type, for fields handed to the caller as-is.

func (Object) Obj

func (o Object) Obj(key string) Object

func (Object) Objs

func (o Object) Objs(key string) []Object

Objs is the objects in a list, skipping anything that is not one.

func (Object) Raw

func (o Object) Raw() map[string]any

func (Object) Str

func (o Object) Str(key string) string

func (Object) Strs

func (o Object) Strs(key string) []string

type TransportError

type TransportError struct {
	Method string
	Path   string
	// Sent is true when the request was written before the failure.
	Sent bool
	// Retried is how many retries were made before giving up.
	Retried int
	Err     error
	// contains filtered or unexported fields
}

TransportError is a request that never got an answer — the connection failed, or it ran past its deadline.

Sent reports whether the request had already gone out. A request that was sent and then timed out may have been acted on: a POST /workflows/run that timed out may still have billed a run, which is why it was not retried.

func NewTransportError

func NewTransportError(method, path string, sent bool, retried int, err error, timeout bool) *TransportError

NewTransportError and MarkUpload set what is kept off the exported fields of TransportError and APIError, for the transport, which builds both.

func (*TransportError) Error

func (e *TransportError) Error() string

func (*TransportError) Is

func (e *TransportError) Is(target error) bool

func (*TransportError) Unwrap

func (e *TransportError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL