Skip to content

Fix fatal error in --prerun/--postrun event hooks (namespaced seeders) - #264

Merged
tihomiro merged 1 commit into
masterfrom
fix/prerun-postrun-event-namespacing
Jun 24, 2026
Merged

tihomiro merged 1 commit into
masterfrom
fix/prerun-postrun-event-namespacing

Conversation

@tihomiro

Copy link
Copy Markdown
Member

Problem

Seeders generated with --prerun / --postrun event hooks fatal at runtime with Error: Class "Database\Seeders\Exception" not found (and the same for Event and the user's event class).

The injected hook code uses unqualified class names:

$response = Event::until(new App\Events\SomeEvent());
if ($response === false) {
    throw new Exception("Prerun event failed, seed wasn't executed!");
}

Since these are emitted inside the stub's namespace Database\Seeders;, PHP resolves them relative to that namespace (Database\Seeders\Event, Database\Seeders\Exception, Database\Seeders\App\Events\SomeEvent) — none of which exist — so the seeder fatals.

Why it went unnoticed

This is a regression from commit 4599ed3 (Oct 2020), which added namespace Database\Seeders; to the seed stub but touched only the .stub files. The event-injection code dates from 2016, when seeders lived in the global namespace where Event/Exception resolved correctly. The combination of the namespaced stub and the rarely-used --prerun/--postrun options is uncommon enough that nobody hit it.

Fix

Prefix the injected Event facade, base Exception, and the user-supplied event class with a leading backslash so they resolve from the global namespace — matching the already-correct \DB:: calls in the same stub.

-$response = Event::until(new $prerunEvent());
+$response = \Event::until(new \$prerunEvent());
...
-throw new Exception("Prerun event failed, seed wasn't executed!");
+throw new \Exception("Prerun event failed, seed wasn't executed!");

Tests

  • Adds testPrerunPostrunEventsAreNamespaceSafe, which asserts the fully-qualified output and loads + executes the generated seeder to prove it no longer fatals. (Fails on the old code, passes on the fix.)
  • Full suite green (7/7).

Manual verification (Laravel 10.48.28, PHP 8.3, MySQL)

  • Common path iseed users — generates, lints, db:seed runs. ✅
  • Event path iseed users --prerun='App\Events\SomePrerunEvent' --postrun='App\Events\SomePostrunEvent' — emits \Event::until(new \App\Events\SomePrerunEvent()), lints, runs without fatal, both hooks fire. ✅

The --prerun/--postrun event-injection code emits unqualified `Event`,
`Exception` and event-class references. Since commit 4599ed3 (Oct 2020)
added `namespace Database\Seeders;` to the seed stub, those names resolve
relative to that namespace (e.g. `Database\Seeders\Exception`) and fatal
at runtime with "Class not found". The injection code dates from 2016,
when seeders lived in the global namespace, so it was never updated for
the namespace migration.

Prefix the injected `Event` facade, base `Exception`, and the
user-supplied event class with a leading backslash so they resolve from
the global namespace, matching the already-correct `\DB::` calls in the
same stub.

Adds a regression test that asserts the qualified output and actually
loads + runs the generated seeder to prove it no longer fatals.
@tihomiro
tihomiro merged commit 15ce002 into master Jun 24, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant