script-development/kendo-error-tracker
Laravel package for tracking application errors, capturing exceptions, and surfacing reports for faster debugging. Helps centralize error visibility and streamline troubleshooting in Kendo-based projects.
kendo is an error tracker for Laravel: you install it, let it capture exceptions/reports, and it groups reports by an anonymised user_hash so you can see how many distinct users a bug affects. Day-to-day you will mostly touch two things: the config file and the ErrorTracker singleton.
First steps:
.env as documented in the README.artisan tinker.user_hash from the authenticated user's id. If your ids are not globally unique (see multi-tenant below), fix that before you rely on affected-user counts.boot():app(\Kendo\ErrorTracker::class)->scopeUserHashUsing(
fn (): int|string|null => tenant()->getKey() // or whatever identifies the tenant
);
The first real use case is triage: open kendo, sort by affected users rather than raw occurrences, and work down the list. That ordering is only trustworthy once user_hash is correct, which is exactly what v0.2.1 addresses.
Centralise tenant scoping in a provider. Register scopeUserHashUsing in a dedicated service provider rather than in middleware or a controller. The resolver is called lazily at report time, so it can read whatever the current request's tenant context is without you having to pass it around. Do not register it per-request — you will stack resolvers and get confusing results.
Treat the resolver as a pure read. It should only read ambient state (current tenant, current request) and return a scalar. Anything with side effects — DB writes, HTTP calls, queue dispatches — will run inside exception handling, where failures are hard to observe and can mask the original error.
Return null deliberately for single-tenant or public/unauthenticated contexts. In v0.2.1 null means "use the v0.2.0 hash exactly", so a single-tenant app that adds a resolver returning null in some paths keeps byte-identical hashes. This makes it safe to roll out the resolver in a mixed codebase — multi-tenant workers get scoped hashes, single-tenant paths stay unchanged.
Use integer or non-empty string tenant keys only. The contract is int|string|null. Empty strings, 0-as-empty-string, models, and UUID objects coerced badly are all footguns. Cast explicitly: fn () => (string) tenant()->getKey() or return null when there is no tenant.
Watch for id collisions in shared-database multi-tenancy too. The fix targets one-database-per-tenant, where ids restart. If you use a single database with a tenant column and composite keys, ids are already unique per user row and you likely do not need a resolver — adding one only fragments hashes for users who legitimately span tenants.
Verify the count before and after rollout. Compare kendo's affected-user count for a known bug before and after deploying the resolver. In a two-tenant app where both tenants have a user id 42, the count should go from 1 to 2. That single check validates the whole change.
scopeUserHashUsing does not widen your data footprint — the tenant identifier stays local. Return values that are themselves sensitive (e.g. an API token) are still a bad idea, because they become part of the hash input.'', a float, or an object produces no hash rather than an error. Type-hint your closure and add a test that asserts the resolver returns int|string|null for each of your tenant states.null returns. Either bind the tenant in the job's handle() and clear it in finally, or accept that job-originated reports are unattributed.scopeUserHashUsing is the supported hook. Do not reach into kendo's internals to rewrite hashes after the fact; you will lose the guarantee that the tenant key never leaves your app.How can I help you explore Laravel packages today?