Skip to content

Reference

FaultGroup model API

use Fissible\Fault\Models\FaultGroup;
$group = FaultGroup::find($id);
// Status checks
$group->isOpen();
$group->isResolved();
$group->isIgnored();
// Status transitions
$group->markResolved('Fixed in PR #123');
$group->markIgnored('Expected during maintenance');
$group->reopen();
// Convenience accessors
$group->shortClass(); // 'QueryException'
$group->relativeFile(); // 'app/Services/UserService.php'

Status workflow

open → markResolved() → resolved
open → markIgnored() → ignored
resolved / ignored → reopen() → open

When FAULT_REOPEN_ON_RECURRENCE=true, fault calls reopen() automatically when a resolved group’s exception is captured again.


fault_groups table schema

ColumnTypeDescription
idbigintPrimary key
fingerprintstring(64)SHA-256 hash of class|file|line
exception_classstringFully-qualified exception class name
filestringAbsolute file path
lineintegerLine number
statusenumopen, resolved, ignored
occurrence_countintegerTotal number of captures
first_seen_attimestampWhen the group was first created
last_seen_attimestampWhen the most recent occurrence was captured
resolved_attimestampWhen it was last resolved
resolution_notetextOptional note from markResolved()
stack_tracetextSample stack trace from the most recent occurrence
created_attimestamp
updated_attimestamp

Test generation workflow

From the fault triage UI at /watch/faults, click Generate Test on any fault group. fault produces a PHPUnit skeleton annotated with @group fault-{hash}:

/**
* @group fault-deadbeef
*/
class FaultDeadbeefTest extends TestCase
{
public function test_reproduces_query_exception_in_user_service(): void
{
// Arrange: reproduce the conditions that triggered the exception
// File: app/Services/UserService.php, line 42
// Act
// ...
// Assert
// ...
}
}

Run the generated test:

Terminal window
php artisan test --filter fault-deadbeef

When the test passes (the bug is fixed), mark the fault group as resolved in the UI.


Fingerprinting

SHA-256 is computed from:

{exception_class}|{relative_file}|{line}

The exception message is intentionally excluded so that exceptions with variable-content messages (containing IDs, timestamps, query strings) map to the same group rather than creating separate groups per message variant.