\Drupal\strata\Health Finding

One thing a tripwire noticed, and the only shape a health signal travels in.

A value object rather than a loose array, because every consumer - the ledger, the circuit breaker, a JSON payload on its way to an operator - reads the same four fields, and an array lets a misspelled key become a silently absent field. Here a missing or misspelled key is a TypeError at the call site: the constructor takes four typed arguments, and fromArray() feeds them positionally, so a bad key arrives as NULL against a string parameter and stops there.

A finding asserts a SYMPTOM. It carries no verdict about a cause and no instruction to repair. What to do about it is RepairLadder's answer, and whether to try again is CircuitBreaker's.

Every field is readonly, so a finding that has been handed to the ledger cannot be edited by whoever reads it back. The properties are declared rather than promoted because scope and context are clamped during construction, and a promoted readonly property cannot be rewritten in the constructor body.

Summary

Methods
Properties
Constants
__construct
severityName
severities
jsonSerialize
fromArray
code
severity
scope
context
INFO
WARN
ERROR
CRITICAL
MAX_SCOPE
MAX_CONTEXT
No protected methods found
No protected properties found
No protected constants found
clamp
No private properties found
No private constants found

Constant

INFO

INFO = 0

Something worth recording that needs nobody to act.

WARN

WARN = 1

A symptom that is tolerable now and will not be if it repeats.

ERROR

ERROR = 2

Something is already wrong; a repair starts at the reindex rung.

CRITICAL

CRITICAL = 3

A restore target may be unusable; the ladder starts at quarantine and waits for a human.

MAX_SCOPE

MAX_SCOPE = 120

Longest scope this will carry.

A scope is a frame hash, a table name or a provider name, all of which fit; anything longer is a caller pasting a payload into the wrong field.

MAX_CONTEXT

MAX_CONTEXT = 400

Longest context this will carry into the ledger.

An unbounded detail column is how a log table becomes the largest thing in the database. The cap is applied here, at construction, rather than at the storage boundary, so every ledger implementation inherits the bound instead of each one having to remember it.

Properties

$code

$code : string

Stable dotted identifier; the circuit breaker and the ladder both key on this.

Type

string —

$severity

$severity : int

One of the severity ordinals on this class.

Type

int —

$scope

$scope : string

What the finding was about: a frame hash, a table, a storage provider.

Type

string —

$context

$context : string

Short human-readable detail, clamped to MAX_CONTEXT on construction.

Type

string —

Methods

__construct()

__construct(string  $code, int  $severity, string  $scope = '', string  $context = '') : mixed

Constructs a finding.

Parameters

string $code

Stable dotted identifier, such as "frame.digest_mismatch".

int $severity

One of INFO, WARN, ERROR or CRITICAL. An ordinal outside that set is kept rather than refused, because the ladder reads severity with >= and so treats an unknown high value as critical, which is the safe direction to be wrong in.

string $scope

What it was about; clamped to MAX_SCOPE.

string $context

Human-readable detail; clamped to MAX_CONTEXT.

Returns

mixed —

severityName()

severityName() : string

Names the severity for a log line or an operator-facing table.

Never parse this back; fromArray() reads the ordinal, which is what the ledger stores.

Returns

string —

INFO, WARN, ERROR, CRITICAL, or UNKNOWN for an ordinal outside the set.

severities()

severities() : array<int,string>

Every severity name, keyed by the ordinal the ledger stores.

Read by a report that has an ordinal out of the database and no finding object to ask.

Returns

array

Ordinal keyed to name, lowest first.

jsonSerialize()

jsonSerialize() : array

Renders the finding as the array it is stored and transported as.

Returns

array —

Keys code, severity, scope and context, which is exactly what fromArray() reads.

fromArray()

fromArray(array  $data) : self

Rebuilds a finding from the array jsonSerialize() produced.

All four keys are required. A missing or misspelled key resolves to NULL and then fails against a typed parameter, which is the whole reason this type exists: a health record that silently lost its scope is worse than one that refused to load.

Parameters

array $data

Keys code, severity, scope and context.

Throws

\TypeError

When a key is absent or holds the wrong type.

Returns

self —

The finding, with scope and context re-clamped.

clamp()

clamp(string  $value, int  $limit) : string

Cuts a string to a byte budget without leaving it unencodable.

A cut on a byte boundary can split a multibyte character, and one invalid sequence makes json_encode() refuse the entire record - so a truncated context would take the whole ledger row down with it. Only a value that was well-formed before the cut is repaired; binary that arrived broken is passed through as-is rather than being eaten a byte at a time.

Parameters

string $value

The string to clamp.

int $limit

Maximum length in bytes.

Returns

string —

At most $limit bytes.