Skip to content

Repository files navigation

LibRuntimeGuard 1.0.0-dev PocketMine-MP 5.0.0+ PHP 8.2+

LibRuntimeGuard

Structured execution boundaries and failure reports for controlled plugin flows.

What It Protects

The first OP-83 slice wraps code that a plugin owns:

  • command handlers;
  • scheduled task callbacks;
  • form response handlers;
  • packet handlers;
  • any custom callback through ErrorBoundary.

It catches Throwable, records sanitized context, preserves the original throwable in the returned result and produces a bounded GuardReport.

It is not an anti-crash layer. Fatal process failures, engine faults and PocketMine-MP lifecycle failures outside the guarded callback remain the responsibility of PHP, PMMP logs and official crash dumps.

Installation

Use the standalone PHAR from the v1.0.0-dev pre-release, or install the official EasyLibrary package:

/easylibrary packages install libruntimeguard development confirm
restart
/elprobe run libruntimeguard

LibRuntimeInspector is optional. When both packages are loaded, EasyLibrary support bundles include Inspector findings translated from guard reports.

Example

use imperazim\runtimeguard\RuntimeGuard;

$guard = (new RuntimeGuard(failureLimit: 100))->register('example-plugin');

$result = $guard->commands()->execute(
    'profile',
    fn(): string => $profileService->render($player),
    owner: 'ExamplePlugin',
    metadata: [
        'sender' => $player->getName(),
        'playerUuid' => $player->getUniqueId()->toString(),
    ]
);

if ($result->isFailure()) {
    $logger->error('Profile command failed.');
}

$payload = $guard->report()->toArray();

Use $result->unwrap() when the caller must rethrow the original failure. Use $result->valueOr($fallback) only when a fallback is a deliberate part of the feature contract.

PMMP Callback Adapters

RuntimeGuard::pmmp() creates small wrappers for PMMP-shaped callbacks. The wrappers do not register commands, tasks, forms or packet handlers for you; they only guard callbacks that your plugin already owns.

use imperazim\runtimeguard\GuardExecutionResult;
use imperazim\runtimeguard\RuntimeGuard;

$guard = (new RuntimeGuard())->register('example-plugin');
$pmmp = $guard->pmmp($this);

$commandHandler = $pmmp->command(
    'profile',
    fn($sender, $command, string $label, array $args): bool => $this->openProfile($sender),
    static function(GuardExecutionResult $result, array $arguments): bool {
        // Optional fallback. Without this handler, the original Throwable is
        // rethrown after being recorded.
        return false;
    }
);

$taskHandler = $pmmp->task('profile-cache-refresh', fn(int $currentTick): void => $this->refreshCache());
$formHandler = $pmmp->form('settings', fn($player, mixed $data): void => $this->saveSettings($player, $data));
$packetHandler = $pmmp->packet('InventoryTransactionPacket', fn($event): void => $this->handlePacket($event));

The adapter extracts scalar metadata such as owner name, sender/player name, UUID, command label, argument count, packet class and response type. It never stores the PMMP objects themselves in the report.

Safety Rules

  • Keep metadata scalar. Do not store Player, Plugin or packet objects.
  • Secret-like metadata keys are redacted.
  • Discord webhook URLs and bearer credentials are redacted from messages.
  • Reports retain only the configured number of recent failures.
  • Source paths are reduced to filenames and trace arguments are never stored.

register() publishes the guard through RuntimeGuardRegistry. This is optional for local use, but enables EasyLibrary doctor/support reports to discover the snapshot without retaining plugin, player or packet objects.

Runtime Inspector

LibRuntimeInspector can consume libruntimeguard.report.v1 through its guard report adapter. The integration is schema-based so both libraries remain usable independently.

About

Structured execution boundaries and failure reports for PocketMine-MP plugin flows.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages