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

Assert Laravel Package

simplesamlphp/assert

A fork of webmozart/assert that lets every assertion throw a custom exception via an extra parameter, falling back to AssertionFailedException. It also adds XML/SAML2-specific assertions for SimpleSAMLphp projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and confirm requirements. The package is a normal Composer library:

composer require simplesamlphp/assert

It pulls in webmozart/assert as a dependency (the fork wraps it), so you do not need to add webmozart/assert yourself — and you should not replace it. There is no service provider, facade, config file, or artisan command. You use the class and call static methods; that is the whole integration.

Where to look first.

  1. The webmozart/assert README — every method there (string, integer, keyExists, uuid, regex, notEmpty, all…, nullOr…, etc.) is available via __callStatic, so that docs page is your method reference.
  2. The custom-assertions table in this package's README — that is the only reason to pick it over webmozart/assert directly. It adds XML/SAML/URI helpers (validURI, validURL, validURN, validDateTime, validNCName, validQName, validDuration, validNMTokens, validNMToken, validHexBinary, stringPlausibleBase64, notInArray).
  3. The simpleSAMLphp/assert test suite for exact edge-case behaviour of the XML/URI validators.

First realistic use case — guarding a value object or DTO where you want a domain exception rather than InvalidArgumentException:

use SimpleSAMLphp\Assert\Assert;
use App\Exceptions\InvalidTenantException;

final class TenantId
{
    public function __construct(private string $value)
    {
        // Fallback to AssertionFailedException (UnexpectedValueException)
        Assert::string($value);
        Assert::uuid($value);

        // Or throw your own exception type
        Assert::notEmpty($value, 'Tenant id is required', new InvalidTenantException());
    }
}

That is the entire value proposition: same assertion catalog as webmozart/assert, but with a third ?Throwable argument, and a saner default exception class (AssertionFailedException extends UnexpectedValueException).


Implementation Patterns

1. Domain-specific exception types instead of InvalidArgumentException

The headline feature. Any assertion accepts a Throwable as the third argument, so your service layer can fail with exceptions your Handler (and Laravel's exception renderer) already understands:

use SimpleSAMLphp\Assert\Assert;
use Illuminate\Validation\ValidationException;

Assert::keyExists($payload, 'id', '', ValidationException::withMessages([
    'id' => 'Missing id in payload',
]));

Because the exception is caught and re-thrown, the original InvalidArgumentException from webmozart/assert never leaks out — verify with expectException() in tests.

2. Invariant checks inside repositories and services

Use Assert for internal invariants (method arguments, array shapes, config), and keep Laravel's Validator for user-facing input. A repository checking its own inputs is the canonical case:

public function findById(string $id, bool $includeTrashed = false): ?Model
{
    Assert::uuid($id);
    return $this->model->withTrashed($includeTrashed)->find($id);
}

3. XML / SAML / URI validation when integrating SSO

This is where the package beats plain webmozart/assert. If you wire SimpleSAMLphp, an IdP, or any SAML2/XML payload into a Laravel app, these checks are genuinely useful:

Assert::validDateTime($assertion->NotOnOrAfter);      // ISO8601 / xs:dateTime
Assert::validURI($entityId);
Assert::validNCName($attributeName);
Assert::validHexBinary($certFingerprint);
Assert::stringPlausibleBase64($encodedResponse);

Treat them as pre-flight checks before pushing a payload into an XML parser or a signature verifier — they fail fast with readable messages instead of a DOMException deep in a library.

4. Config validation in a service provider

Because there is no package config, use Assert to validate your config at boot:

public function register(): void
{
    $config = config('services.saml');

    Assert::keyExists($config, 'entity_id');
    Assert::validURI($config['entity_id']);
    Assert::validURL($config['idp_sso_url']);
    Assert::notInArray($config['entity_id'], config('services.saml.blocklist', []));
}

Failing loudly at container boot is far cheaper than a cryptic error on the first request.

5. Value-object constructors and factory methods

Pair each assertion with the property it guards so failures read like documentation. Prefer the nullOr…/all… variants from webmozart/assert where they exist rather than hand-rolling loops.

6. Testing

Assertions are perfectly testable with PHPUnit — no mocking required:

$this->expectException(InvalidTenantException::class);
new TenantId('not-a-uuid');

For the AssertionFailedException fallback, assert on UnexpectedValueException (its parent), not InvalidArgumentException.


Gotchas and Tips

It is not a Laravel package. Several third-party write-ups misdescribe Assert::enum(), Assert::extend(), Assert::custom() and a Laravel service provider — none of those exist. The only method surface is (a) webmozart/assert's catalogue via __callStatic, plus (b) the fixed list of XML/URI helpers in the README. Do not plan around a validator/facade integration.

Enums (v1.5.0) are formatting, not validation. The 1.5.0 change "add support for enums in error message" means an enum value renders properly in the failure message. It is not a new enum() assertion. Validate enums yourself (in_array($value, Cases, true) on a BackedEnum via ->value) and pass your own message.

Stricter regex in 1.5.0. Trailing newlines at end-of-line are now rejected. If you validated multi-line input with Assert::regex() and relied on the old behaviour, you will start seeing failures — trim() or adjust the pattern deliberately, and check regression tests after upgrading from 1.4.x.

Catch UnexpectedValueException, not InvalidArgumentException. The whole point of the fork is that AssertionFailedException extends UnexpectedValueException. Catching InvalidArgumentException around this package will silently miss failures.

__callStatic and static analysis. webmozart/assert methods are dispatched through __callStatic, so IDE autocompletion and PHPStan may not know they exist. The package ships PHPStan-friendly stubs; if your project is on a different PHPStan version, add a @method docblock or a stub file in phpstan.neon rather than assuming autocompletion will resolve.

Exception construction cost. new InvalidTenantException() (or a ValidationException::withMessages([...])) is evaluated eagerly on every call, even when the assertion passes. In hot paths (bulk imports, tight loops), don't pass an expensive exception instance — either accept the default AssertionFailedException or pass a lazily-built one via a small closure/helper.

Stack traces point at the wrapper. The package catches InvalidArgumentException and re-throws, so the trace originates inside the package, not at your call site. When debugging, check the assertion message (and custom exception) rather than the top stack frame. Pass a message for every non-trivial assertion; the default messages are generic.

Message placeholders. The underlying library supports {{ value }}-style placeholders in messages; a long value gets truncated/dumped into the exception, which ends up in logs. Keep payloads out of messages where confidentiality matters.

Composer conflicts. Constrain simplesamlphp/assert to a range whose webmozart/assert requirement matches the rest of your dependency tree; a stray webmozart/assert constraint is the most common install failure. There is no configuration to "fix" afterwards — resolving the constraint is the fix.

Debugging tip. When a check fails unexpectedly in development, run the same value through the raw webmozart equivalent to isolate whether the failure is the fork's wrapper (exception type, message) or the actual assertion logic (type juggling, e.g. "123" vs 123 for Assert::integer).

Extension points. There is no extend()/register() mechanism. Extension means subclassing or writing a small project-local facade that wraps Assert calls and centralises your message/exception conventions:

final class Guard
{
    public static function uuid(mixed $v, string $field): string
    {
        Assert::uuid($v, sprintf('Invalid %s', $field), new InvalidTenantException($field));
        return $v;
    }
}

When not to use it. If you never need custom exception types and never touch XML/SAML/URI validation, webmozart/assert alone (or Laravel's Validator/Exceptions) is a smaller dependency for the same result. This package's 7 stars and 0 dependents reflect that it is effectively SimpleSAMLphp's internal utility published for reuse — adopt it deliberately for the XML/SAML helpers or the exception-passing API, not as a general Laravel validation layer.

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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log