timefrontiers / php-instance-error
PHP Instance Error handler with access-based filtering
Package info
github.com/timefrontiers/php-instance-error
pkg:composer/timefrontiers/php-instance-error
Requires
- php: ^8.5
- timefrontiers/php-core: ^1.0
- timefrontiers/php-error-log: ^1.0
- timefrontiers/php-has-errors: ^1.0
Requires (Dev)
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^10.0
Suggests
- timefrontiers/php-session: For automatic rank detection via global $session
This package is auto-updated.
Last update: 2026-08-20 07:45:58 UTC
README
InstanceError is the standard reader and access-rank filter for error
collections produced by TimeFrontiers\Helper\HasErrors. It preserves the
established five-element tuple and context grouping used across TimeFrontiers
packages.
Installation
composer require timefrontiers/php-instance-error
The package requires timefrontiers/php-error-log, so the public log() API is
available after every normal Composer installation. timefrontiers/php-session
remains optional; without a valid global session, extraction defaults to guest
rank.
Canonical error shape
Every accepted error is a five-element list:
/** @var array{0: int, 1: int, 2: string, 3: string, 4: int} $error */ $error = [$minimumRank, $code, $message, $file, $line];
Errors are grouped by a non-empty context:
/** @var array<string, list<array{0: int, 1: int, 2: string, 3: string, 4: int}>> $errors */ $errors = [ 'validation' => [ [0, 400, 'Invalid email address.', '/app/User.php', 42], ], ];
Malformed contexts and tuples are rejected during extraction. In particular, a missing or invalid minimum rank never defaults to guest. Safe integer-like strings in numeric tuple positions are normalized to integers; fields are not invented when missing.
Extracting errors for display
Objects using HasErrors::getErrors() are supported directly. A public legacy
$errors property is used only when there is no callable getter.
use TimeFrontiers\InstanceError; $extractor = new InstanceError($service); // Grouped tuples visible to the current session rank. $visible = $extractor->get(); // Flat list of tuples from one context. $validation = $extractor->get('validation'); // Flat list of strings from one context. $validationMessages = $extractor->get('validation', true);
get('', true) does not flatten across contexts. It returns grouped message
lists:
$groupedMessages = $extractor->get('', true); // ['validation' => ['Invalid email address.'], 'save' => ['Save failed.']] $flatMessages = $extractor->messages(); // ['Invalid email address.', 'Save failed.']
Helper methods operate only on entries visible to the resolved rank:
if ($extractor->has('validation')) { $first = $extractor->first('validation'); $count = $extractor->count('validation'); }
Rank filtering is defense in depth, not secret scrubbing. Public responses must not contain SQL, stack traces, absolute paths, provider payloads, credentials, tokens, cookies, authorization headers, card data, or raw driver messages.
Rank resolution
The effective visibility rank is resolved in this order:
- An explicit
AccessRankconstructor override. - An explicit integer constructor override.
true, which deliberately bypasses filtering withPHP_INT_MAX.- The callable global
$session->access_rank()method. - A public legacy global
$session->access_rankproperty. AccessRank::GUEST->value.
Session method/property results may be an AccessRank, integer, or integer-like
string. Invalid, negative, inaccessible, or throwing session values fail to
guest. Future integer ranks are not capped; the current enum includes
AccessRank::OWNER at rank 14.
use TimeFrontiers\AccessRank; use TimeFrontiers\InstanceError; $developerView = new InstanceError($service, AccessRank::DEVELOPER); $rankFiveView = new InstanceError($service, 5);
Explicit rank overrides, the true bypass, and all() are trusted server-side
technical/debug operations. Never populate an override from a query parameter,
form field, header, token claim, or any other untrusted request input. Never
return all() or unrestricted output in a public response.
Technical logging
log() applies the extractor's current visibility rank and writes one
ResponseStatus::PROCESS_ERROR record per selected context. Each log detail
keeps the tuple's own code separate from the response-status prefix.
use TimeFrontiers\InstanceError; // Logs only errors visible to the normal session-resolved extractor. $displayExtractor = new InstanceError($service); $displayExtractor->log('validation'); // Trusted server-side flow: deliberately include all technical entries. $technicalExtractor = new InstanceError($service, true); $technicalExtractor->log(); // Preserve the exact custom-file behavior through ErrorLog::setFile(). $technicalExtractor->log('database', '/var/log/my-app/database-errors.log');
A supplied context that does not exist, a failed write, or a logger exception
returns false and adds a safe developer-visible diagnostic to the extractor's
own HasErrors collection.
Logging does not make secrets safe to store. The logger protects its record delimiters, but application and package code must prevent credentials, tokens, card data, raw provider payloads, and other secrets from entering error messages in the first place.
Adding canonical errors
put() is a programmer-facing API. It throws InvalidArgumentException for a
blank context or malformed tuple.
$extractor->put('custom', [ AccessRank::GUEST->value, 400, 'Something went wrong.', __FILE__, __LINE__, ]);
Using HasErrors
use TimeFrontiers\Helper\HasErrors; final class Service { use HasErrors; public function process():bool { $this->_userError('process', 'The request could not be processed.', 400); return false; } }
The current protected _addError() signature is:
_addError( string $context, string $message, int $minimumRank = AccessRank::GUEST->value, int $code = 256, string $file = '', int $line = 0, ): void
Development
composer validate --strict
composer install
composer test
composer analyse
composer audit
Dependencies
- PHP 8.5 or newer
timefrontiers/php-coretimefrontiers/php-has-errorstimefrontiers/php-error-log- Optional:
timefrontiers/php-sessionfor global session-rank resolution
License
MIT