lendable/form-error-log-bundle
A Symfony bundle that captures and logs form validation errors, so you can trace failed form submissions, debug validation issues, and monitor error patterns across your application.
Architecture fit — the headline finding is unchanged. lendable/form-error-log-bundle is still a Symfony bundle, not a Laravel package. v2.0.0 changing the autoloading strategy from PSR-0 to PSR-4 is a Composer packaging detail: it changes how the autoloader resolves class names to paths. It does not add a service provider, a config/ publishable asset, a facade, or an auto-discovery entry, and it does not boot the FormEvents::POST_SUBMIT subscriber outside Symfony's DI container and HttpKernel. Installing it into a Laravel application still registers nothing and executes nothing. The distinction matters because "major version released" reads as "revived" in a dependency review, and it is not — the release contains no capability the prior version lacked.
Integration feasibility — the pattern remains portable; the artifact remains not. The functional idea is still ~40–80 lines natively: a middleware catching ValidationException around $next($request), or a base FormRequest overriding failedValidation(), logging field path, rule, form, and a correlation ID. v2.0.0 does not reduce that work by a single line. Build-vs-adopt still resolves to build.
Technical risk — high, but the nature of the risk has changed from "known-dead" to "unverified liveness." The prior assessment recorded the repository as archived, last released 2017-11-24, 0 stars, 0 dependents. The existence of a v2.0.0 release contradicts at least one of those data points, and no refreshed repository metadata was supplied — the release note is the sole evidence in front of us. That is a verification gap, not a reason to adopt. Critically, a PSR-4 migration is a mechanical composer.json plus directory-layout change; it is not evidence of PHP 8 return-type fixes, Symfony 5/6/7 support, a security policy, CI, or a responsive maintainer. The base case should remain "effectively unmaintained until proven otherwise." And note the asymmetry: even a fully maintained Symfony bundle still fails the Laravel fit test, so improved maintenance can never move the verdict — only the risk narrative.
Key questions for the requestor.
SECURITY.md. The prior figures are now stale and must be re-baselined.FormRequest) or does any part of the stack genuinely run Symfony?Verdict: unchanged — do not adopt the dependency. A major version that only modernises autoloading does not close the platform gap. Reimplement the pattern natively in Laravel under our own ownership and route output to a product-analytics sink. The one action item the release creates is a re-verification of the dependency register entry, not a reconsideration of the decision.
Stack fit. Unchanged, and unchanged for a structural reason: PSR-4 versus PSR-0 is invisible to the framework layer. The concept still fits Laravel at exactly one seam — the validation failure boundary — where ValidationException::errors() gives a structured field→message map that is richer than what the bundle extracts from FormErrorIterator. There is no adapter, shim, or polyfill that makes a Symfony bundle into a Laravel package, and v2.0.0 does not claim to be one. For stakeholders: there is no supported migration path from this package into a Laravel codebase. The choice is reimplement or abandon.
Migration path. Greenfield for us. Sequence: (1) obtain the full changelog and refreshed repo metadata; (2) confirm target forms and event schema with the product owner; (3) define a FormValidationFailed event carrying form, route, field, rule, session_id, user_id (nullable), and a salted hash of the submitted value rather than the value; (4) implement as middleware, not a base FormRequest, for coverage of controller- and Validator::make-triggered validation; (5) ship behind a config flag, off by default, enabled per environment; (6) add sampling and rate limiting before production enablement.
Compatibility. Two separate notes. For us: our implementation targets the Laravel version already pinned by the application, so compatibility is inherited rather than negotiated — still the decisive advantage. For any Symfony service in the estate: v2.0.0 is a breaking autoload change. PSR-0 class strings resolved by convention (Lendable\…\FormErrorLogBundle) will no longer autoload; any YAML/XML service definition, class: parameter, DI alias, or serialized payload referencing the old scheme must be audited before upgrading. This is the only actionable technical item in the release, and it applies exclusively to Symfony consumers — of which, per the current estate, there may be none.
Sequencing. Phase 0 (new): verify liveness and read the full changelog; confirm whether any Symfony footprint exists that would be affected by the autoload change. Phase 1: emit to a dedicated structured-log channel at debug/info to characterise volume and schema. Phase 2: promote to the analytics pipeline once volume is known, and downgrade the log channel. Phase 3: build the usability reporting — top failing fields, top failing rules per form, abandonment correlation — which is the actual deliverable and was never in scope for the original package.
Maintenance. The "frozen since 2017" framing must be corrected in the register, but the conclusion stands: first-party code at ~60 lines remains cheaper to own than a third-party dependency whose support posture is unclear. The new failure mode to price in is subtler — a package that ships occasional hygiene releases with no stated support policy is arguably a worse dependency signal than one that is cleanly archived, because it projects health without demonstrating it. Either way, the recurring costs are unchanged: annual safety reviews, blocked framework upgrades when the abandoned constraint cannot resolve, and an unbounded CVE-response gap. Budget roughly an hour for the Phase 0 verification.
Support. Improved in principle, unproven in fact. We have one release note and no evidence of issue triage, response times, or a security disclosure channel. Do not represent this as a supported component until the repo metadata confirms otherwise. If the project has genuinely been adopted by a new maintainer, that is a real improvement — but it improves the Symfony story only and leaves the Laravel story at zero.
Scaling. Unchanged. Write volume: one entry per field error per failed submit, dominated by bot, credential-stuffing, and scraping traffic rather than genuine user friction — corrupting the usability signal and inflating storage cost. Mitigate with sampling, per-IP/session rate limiting, and bot-signature exclusion before broad enablement. Query cost: application logs are poor at "top 20 failing fields last week"; land the data in the warehouse where aggregation is cheap and retention is deliberate.
Failure modes. Four to design against. (1) PII leakage — validation messages echo submitted values; log rule and field, not message body, or scrub aggressively. Highest severity, most likely to produce an incident. (2) Log flooding / cost blowout from hostile traffic. (3) Silent no-op — precisely what the bundle would produce in a Laravel app, and what an upgrade to v2.0.0 would still produce; only an integration test asserting an emitted entry on a real failed validation catches it. (4) Exception masking — logging inside the validation boundary must never throw, never swallow, and never alter the ValidationException; wrap and rethrow unconditionally.
Ramp-up. Essentially unchanged. One engineer, one to two days including tests for the reimplementation, plus ~1 hour for Phase 0 verification. Ramp-up on the original bundle remains higher in practice, because an engineer must first discover it does nothing in Laravel — a dead end that costs half a day and returns a recommendation to reimplement. Staff as a small platform/observability task owned by the backend team, with the product owner defining which forms matter and which fields represent a usability defect versus expected validation friction.
How can I help you explore Laravel packages today?