taskerror

package
v0.0.19 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package taskerror is the leeway-coded wire form of the terminal-failure payload published on `task.<id>.error`. Fourth broker DTO to migrate off the buscodec fxamacker-cbor default onto the ADR-0042 SoA codec.

Every field maps to an existing shared vocabulary entry:

  • vdd.MembTaskId — subject id (since taskprogress).
  • vdd.MembReason — short failure rationale (since taskcancel).
  • vdd.MembErrorText — rendered error chain; new shared term introduced with this migration, reusable by future DTOs that surface a captured error alongside their payload.

Wire shape vs the legacy task.TaskError JSON form:

  • `Id TaskIdT` → `TaskId string`.
  • `AtMs` → `At` (codec plain `ts` is a `time.Time`; producers convert via `time.UnixMilli` at the wire boundary).
  • New `FactId uint64` plain `id`.
  • `Error []byte` → `ErrorText string`. The producer captures `eh.FormatErrorWithStackS(taskErr)` — already a UTF-8 multi-line rendering — and the codec stores it in a text-section column. Callers that previously read `e.Error` as `[]byte` now read `e.ErrorText` as `string` (or `[]byte(e.ErrorText)` for the legacy reader surface).

When a structured eh.MarshalError CBOR/JSON envelope is eventually added to the wire, it lands as a separate column (e.g. `errorStructured`), not by changing ErrorText's section — text stays the human-readable column observers render directly.

Index

Constants

This section is empty.

Variables

View Source
var PackageProps = packageprops.Props{
	WASMWASI:         packageprops.WASMBlocked,
	WASMJS:           packageprops.WASMBlocked,
	WASMFreestanding: packageprops.WASMBlocked,
}

PackageProps records this package's curated properties (ADR-0080). Seeded by `wasmsurvey props generate`; curate by hand, then `wasmsurvey props verify`.

View Source
var TaskErrorActiveFields = sync.OnceValue(func() []int {
	active := map[string]bool{"stringArray": true, "textArray": true}
	schema := cbdml.CreateSchemaFacts()
	out := make([]int, 0, 4+len(active)*8)
	for i, f := range schema.Fields() {
		name := f.Name
		switch {
		case strings.HasPrefix(name, "id:"),
			strings.HasPrefix(name, "ts:"),
			strings.HasPrefix(name, "lc:"):
			out = append(out, i)
		case strings.HasPrefix(name, "tv:"):
			rest := name[3:]
			colon := strings.IndexByte(rest, ':')
			if colon < 0 {
				continue
			}
			if active[rest[:colon]] {
				out = append(out, i)
			}
		}
	}
	return out
})

TaskErrorActiveFields is the column-index subset this kind populates in the boxer.facts Arrow schema. Lazily computed once via sync.OnceValue: scans cbdml.CreateSchemaFacts()'s tv:<section>:... field names against this kind's active sections plus the three plain prefixes (id:, ts:, lc:). Driven through RecordBuilder. SetActiveFields to skip per-row emit walks for unused columns.

View Source
var TaskErrorActiveSections = []int{9, 12}

TaskErrorActiveSections is the dml_cbor section-index subset this kind populates. Passed to InEntityFacts.SetActiveSections so the builder skips beginSection list-slot work for inactive sections.

Functions

func TaskErrorAddSections added in v0.0.17

func TaskErrorAddSections[
	StringArrayAttr TaskErrorStringArrayAttrI,
	StringArraySec TaskErrorStringArraySecI[StringArrayAttr, Ent],
	TextArrayAttr TaskErrorTextArrayAttrI,
	TextArraySec TaskErrorTextArraySecI[TextArrayAttr, Ent],
	Ent any,
	DML TaskErrorEntityI[
		StringArrayAttr, StringArraySec,
		TextArrayAttr, TextArraySec,
		Ent,
	],
](dml DML, row TaskError) (err error)

TaskErrorAddSections contributes this kind's tagged sections to the OPEN entity on dml — the BuildEntities body without the entity frame. The caller owns BeginEntity / plain setters / CommitEntity.

func TaskErrorBuildEntities

func TaskErrorBuildEntities[
	StringArrayAttr TaskErrorStringArrayAttrI,
	StringArraySec TaskErrorStringArraySecI[StringArrayAttr, Ent],
	TextArrayAttr TaskErrorTextArrayAttrI,
	TextArraySec TaskErrorTextArraySecI[TextArrayAttr, Ent],
	Ent any,
	DML TaskErrorEntityI[
		StringArrayAttr, StringArraySec,
		TextArrayAttr, TextArraySec,
		Ent,
	],
](dml DML, c *TaskErrorColumns) (err error)

TaskErrorBuildEntities walks c row-by-row, drives dml's entity / section chain, and returns once every row has been committed. The dml argument's concrete type binds every type parameter via Go's type inference at the call site.

func TaskErrorFillFromArrow

func TaskErrorFillFromArrow[
	StringArrayAttrs TaskErrorStringArrayAttrsReadI,
	StringArrayMembs TaskErrorStringArrayMembsReadI,
	TextArrayAttrs TaskErrorTextArrayAttrsReadI,
	TextArrayMembs TaskErrorTextArrayMembsReadI,
](
	c *TaskErrorColumns,
	n int,
	idCol *array.Uint64,
	nkCol *array.Binary,
	tsCol *array.Timestamp,
	stringArrayAttrs StringArrayAttrs,
	stringArrayMembs StringArrayMembs,
	textArrayAttrs TextArrayAttrs,
	textArrayMembs TextArrayMembs,
) (err error)

TaskErrorFillFromArrow walks rec row-by-row and appends each entity's plain + tagged-section values into c. Plain columns enter as concrete Arrow accessors; per-section Attrs + Membs bind through type-parameter interfaces.

Types

type TaskError

type TaskError struct {

	// FactId is the per-row event id; distinct from TaskId (the
	// subject of the failure).
	FactId uint64 `lw:",id"`

	// NaturalKey is the entity natural key; the facts SetId is 2-arg.
	// These bus DTOs carry no separate key, so it stays the nil default.
	NaturalKey []byte `lw:",naturalKey"`

	// At is the event timestamp. time.Time matches the facts
	// SetTimestamp signature directly (strict 1:1); the leeway wire
	// truncates to u32 seconds, while the bus preserves full nanos.
	At time.Time `lw:",ts"`

	// TaskId names the task that failed.
	TaskId string `lw:"taskId,stringArray"`

	// Reason is a short human-readable rationale (often the
	// underlying error's .Error() short form). Empty when the
	// producer didn't supply one.
	Reason string `lw:"reason,textArray"`

	// ErrorText is the FormatErrorWithStackS rendering of the
	// captured error chain. Empty when the producer surfaced a
	// reason-only failure with no Go error attached.
	ErrorText string `lw:"errorText,textArray"`
	// contains filtered or unexported fields
}

TaskError is the wire payload published once at task failure on subject `task.<id>.error`. ErrorText carries the producer's FormatErrorWithStackS rendering of the failure (multi-line text); observers render it directly via the errorview widget.

func TaskErrorReadRow added in v0.0.17

func TaskErrorReadRow[
	StringArrayAttrs TaskErrorStringArrayAttrsReadI,
	StringArrayMembs TaskErrorStringArrayMembsReadI,
	TextArrayAttrs TaskErrorTextArrayAttrsReadI,
	TextArrayMembs TaskErrorTextArrayMembsReadI,
](
	i int,
	stringArrayAttrs StringArrayAttrs,
	stringArrayMembs StringArrayMembs,
	textArrayAttrs TextArrayAttrs,
	textArrayMembs TextArrayMembs,
) (row TaskError, present bool, err error)

TaskErrorReadRow reads row i as one optional TaskError component: presence- gated (a row carrying none of the kind's memberships yields present=false), membership-matched. A slot carrying more attributes than this kind's shape admits is an error, for every shape including containers. Plain- bound fields stay zero — the caller owns the envelope. The Attrs/Membs readers bind by type inference at the call site, as with FillFromArrow.

type TaskErrorCodec

type TaskErrorCodec struct{}

TaskErrorCodec is the buscodec.CodecI bridge for TaskError. Encodes one row through dml_cbor; decodes via cborarrow.Convert + ra-Unmarshal + Row(0). Auto-registered in init() so callers using buscodec.Encode / Decode route through here instead of the CBOR fallback.

func (*TaskErrorCodec) ContentType

func (inst *TaskErrorCodec) ContentType() (ct string)

func (*TaskErrorCodec) Decode

func (inst *TaskErrorCodec) Decode(b []byte, v any) (err error)

func (*TaskErrorCodec) Encode

func (inst *TaskErrorCodec) Encode(v any) (b []byte, err error)

func (*TaskErrorCodec) Name

func (inst *TaskErrorCodec) Name() (n string)

type TaskErrorColumns

type TaskErrorColumns struct {
	FactId     []uint64
	NaturalKey [][]byte
	At         []time.Time

	TaskId    []string
	Reason    []string
	ErrorText []string
}

TaskErrorColumns is the SoA storage for batches of TaskError rows. All slices grow in lockstep — Len returns the row count.

func (*TaskErrorColumns) Append

func (c *TaskErrorColumns) Append(row TaskError)

Append pushes one AoS record into the SoA buffers.

Aliasing: slice and pointer fields (`[]T`, `*roaring.Bitmap`) are stored by reference, not copied. Callers must not mutate row.<F> after Append unless they want Marshal to read the mutation. Scalar fields (T, Option[T]) are copied by value.

func (*TaskErrorColumns) Len

func (c *TaskErrorColumns) Len() int

Len returns the number of rows currently in the batch.

func (*TaskErrorColumns) Marshal

func (c *TaskErrorColumns) Marshal(w io.Writer) (err error)

Marshal writes the SoA buffer to w as the sparse-CBOR wire format produced through factsschema/dml_cbor. Thin wrapper around TaskErrorBuildEntities — the per-row chain lives there and works against any leeway-DML class that structurally satisfies TaskErrorEntityI.

func (*TaskErrorColumns) Row

func (c *TaskErrorColumns) Row(i int) (row TaskError)

Row reconstructs entity i as an AoS TaskError record. Inverse of Append: slice / pointer fields are shared by reference (no defensive copy); scalar fields and Option[T] are copied.

func (*TaskErrorColumns) Unmarshal

func (c *TaskErrorColumns) Unmarshal(rec arrow.Record) (err error)

Unmarshal appends one row to c per entity in rec, projecting the boxer.facts columns through factsschema/ra. Thin wrapper around TaskErrorFillFromArrow — the per-row decode lives there.

type TaskErrorEntityI

type TaskErrorEntityI[
	StringArrayAttr TaskErrorStringArrayAttrI,
	StringArraySec TaskErrorStringArraySecI[StringArrayAttr, Ent],
	TextArrayAttr TaskErrorTextArrayAttrI,
	TextArraySec TaskErrorTextArraySecI[TextArrayAttr, Ent],
	Ent any,
] interface {
	BeginEntity() Ent
	SetId(id uint64, naturalKey []byte) Ent
	SetTimestamp(ts time.Time) Ent
	GetSectionStringArray() StringArraySec
	GetSectionTextArray() TextArraySec
	CommitEntity() (err error)
}

TaskErrorEntityI is the entity-builder surface TaskErrorAddSections drives. It always lists the per-section getters; the entity-frame methods (BeginEntity / plain setters / CommitEntity) are added only for the full codec's BuildEntities. AddSections stacks sections onto a frame the caller already owns, so it needs none of them — which lets a store drive it with a builder whose frame control is unexported (ADR-0100 SD6). Ent is the builder pointer.

type TaskErrorStringArrayAttrI

type TaskErrorStringArrayAttrI interface {
	dmlruntime.InAttributeMembershipLowCardRefPI
	EndAttributeP()
}

TaskErrorStringArrayAttrI is the InAttr-side view of the stringArray section. P-variants only — every method returns void so no F-bounded `[Self]` parameter is needed.

type TaskErrorStringArrayAttrsReadI

type TaskErrorStringArrayAttrsReadI interface {
	GetAttrValueSingleOrDefault(entityIdx raruntime.EntityIdx, attrIdx raruntime.AttributeIdx) string
	GetNumberOfAttributes(entityIdx raruntime.EntityIdx) int64
}

TaskErrorStringArrayAttrsReadI is the Attributes-side view of the stringArray section.

type TaskErrorStringArrayMembsReadI

type TaskErrorStringArrayMembsReadI interface {
	GetMembValueLowCardRef(entityIdx raruntime.EntityIdx, attrIdx raruntime.AttributeIdx) iter.Seq[uint64]
}

TaskErrorStringArrayMembsReadI is the Memberships-side view of the stringArray section.

type TaskErrorStringArraySecI

type TaskErrorStringArraySecI[Attr any, Ent any] interface {
	BeginAttributeSingle(value string) Attr
	EndSection() Ent
}

TaskErrorStringArraySecI is the Section-side view: opens an attribute and closes the section. Attr and Ent are bound at the call site by inference.

type TaskErrorTextArrayAttrI

type TaskErrorTextArrayAttrI interface {
	dmlruntime.InAttributeMembershipLowCardRefPI
	EndAttributeP()
}

TaskErrorTextArrayAttrI is the InAttr-side view of the textArray section. P-variants only — every method returns void so no F-bounded `[Self]` parameter is needed.

type TaskErrorTextArrayAttrsReadI

type TaskErrorTextArrayAttrsReadI interface {
	GetAttrValueSingleOrDefault(entityIdx raruntime.EntityIdx, attrIdx raruntime.AttributeIdx) string
	GetNumberOfAttributes(entityIdx raruntime.EntityIdx) int64
}

TaskErrorTextArrayAttrsReadI is the Attributes-side view of the textArray section.

type TaskErrorTextArrayMembsReadI

type TaskErrorTextArrayMembsReadI interface {
	GetMembValueLowCardRef(entityIdx raruntime.EntityIdx, attrIdx raruntime.AttributeIdx) iter.Seq[uint64]
}

TaskErrorTextArrayMembsReadI is the Memberships-side view of the textArray section.

type TaskErrorTextArraySecI

type TaskErrorTextArraySecI[Attr any, Ent any] interface {
	BeginAttributeSingle(value string) Attr
	EndSection() Ent
}

TaskErrorTextArraySecI is the Section-side view: opens an attribute and closes the section. Attr and Ent are bound at the call site by inference.

Jump to

Keyboard shortcuts

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