Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Safe Laravel Package

nette/safe

nette/safe is a lightweight Nette library providing exception-throwing wrappers for risky PHP functions, helping Laravel and PHP projects fail loudly instead of silently returning false. It offers safer file, stream, and process helpers for more reliable error handling.

View on GitHub
Deep Wiki
Context7

Getting Started

nette/safe is an archived, discontinued package; treat any adoption as a legacy maintenance decision, not a new dependency. Before anything else, confirm the code you're touching already depends on it (composer show nette/safe) rather than reaching for it on a fresh project — the actively maintained equivalent is thecodingmachine/safe, and new code should use that instead.

If you're working inside an existing codebase that already has it:

  1. composer require nette/safe (or confirm it's in composer.json).

  2. Inspect vendor/nette/safe/src/ first. The package ships a set of namespaced wrapper functions under Nette\Safe plus an internal error-handler mechanism that traps PHP warnings and converts them into a thrown exception. The exact exception class name matters for catch blocks — verify it in the source rather than assuming \Exception.

  3. Check how the package is autoloaded. Function-based libraries register their functions via a files entry in composer.json; run composer dump-autoload after adding or updating the dependency, otherwise calls to Nette\Safe\... will fatal with "undefined function".

  4. First real use case: replace a false-returning built-in that silently corrupts flow. Instead of:

    $contents = file_get_contents($path);
    if ($contents === false) { /* often forgotten */ }
    

    use the wrapped equivalent and let the failure surface as an exception:

    try {
        $contents = \Nette\Safe\file_get_contents($path);
    } catch (\Throwable $e) {
        // handle missing file, permission denied, etc.
    }
    

Start with file_get_contents, fopen, mkdir, unlink, json_decode-adjacent utilities — the calls where a silent false or warning is easiest to overlook.

Implementation Patterns

Replace-and-catch at the I/O boundary. The package is most valuable at the edges of your application: filesystem, streams, and process handling. Wrap those calls and let exceptions bubble to a handler that can log context (path, operation) — something the original false return could never carry.

Localized error-handler scoping. Because the package works by installing an error handler around the call, keep wrapper usage inside narrow try/catch blocks rather than sprinkling it through a long method. This prevents one caught warning from masking an unrelated notice later in the same function.

Adopt incrementally behind a small facade. In a large legacy codebase, don't rewrite every file_get_contents. Introduce a thin helper — e.g. App\Support\Files::read() — that internally calls Nette\Safe\file_get_contents. That gives you one place to swap the implementation later (to thecodingmachine/safe or native try/finally logic) when you finally retire the archived package.

Translate to domain exceptions. Catch Nette\Safe's exception at the boundary of your service and rethrow a domain-specific one (FileUnreadableException, StorageException). This keeps the discontinued package's API from leaking through your whole codebase and makes the eventual removal a mechanical change.

Pair with transactions/cleanup. Use exceptions as the trigger for rollback or cleanup: an exception from a wrapped fopen/flock/rename should flow into a finally that releases handles. This is exactly where silent false returns used to leave dangling state.

Testing. Assert on thrown exception type, not just the boolean result. Because the wrapper converts warnings to exceptions, a test that used to check assertFalse($result) becomes expectException(...), which documents the failure mode far better.

Gotchas and Tips

  • It's archived. No security patches, no PHP 8.x compatibility guarantees going forward. Pin the version, audit it against your PHP version, and track it as tech debt with a replacement plan.
  • Error-handler interaction is the sharp edge. The package relies on intercepting PHP errors/warnings. If your app or framework (or another library) installs its own handler, ordering and set_error_handler/restore_error_handler balance can break — you may see warnings leak through as warnings, or worse, get swallowed. Debug by checking set_error_handler(null) state and whether a framework bootstrap re-registers handlers after the wrapper runs.
  • @ suppression and error_reporting. Suppressed calls and restrictive error_reporting settings can prevent the wrapper from seeing a warning. If a call that should throw instead returns false, check for a leading @ or a level that filters E_WARNING.
  • Not every function is covered. Don't assume symmetry with the full PHP API surface. Grep the package's source for the exact function name before relying on a Nette\Safe\ variant; otherwise you'll get an "undefined function" fatal.
  • catch (\Throwable) vs catch (Exception). Determine whether the wrapper throws an Error-derived class; catching only \Exception can miss it. Catch \Throwable at boundaries and narrow from there.
  • Autoload caching in CI. Function autoloading via files is sensitive to stale vendor/composer/autoload_files.php. If CI sees "undefined function" but local doesn't, run composer dump-autoload --optimize and clear caches.
  • Migration path is the real tip. If you're touching this in a new feature, wrap the dependency now: create the facade, write tests against the facade, then swap to thecodingmachine/safe (which has a broader function set and active maintenance) behind it. The call sites stay unchanged.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin