What happens
A client error report carries message, type, stack, route and version — but nothing that identifies the account that hit the failure, even when the customer is signed in and the app already knows it.
The resulting log line looks like this:
Client error: client="dfx-services" route="/buy" version="…" userAgent="…" type="ChunkLoadError" message="Loading chunk 2688 failed. …"
So the record answers what broke and where, but never who it happened to.
Why it matters
When a customer reports "I can't buy anything, it keeps showing something went wrong", there is no way to look up whether that customer's failure is among the recorded ones — nor how often it hit them, nor whether it stopped.
This is not hypothetical. A support report was checked against the logs today: the failures were in there, but tying them to the reporting customer took a chain of indirect evidence — correlating the time the support entry was updated, resolving client IPs out of trace data, and observing that the customer produced no purchase requests at all during the affected window because the page never loaded far enough. The conclusion stayed circumstantial, and it only worked because the incident happened to be recent and narrow. For anything older, or during a busy period, the same question cannot be answered at all.
An account id in the report turns that reconstruction into a single lookup.
Proposed change
1. API — accept and record the field (must come first)
CreateClientErrorDto gains an optional numeric account id, and ClientErrorService logs it as its own key=value field so it stays queryable:
Client error: client="…" account="123456" route="/buy" …
This step is a prerequisite, not a nicety: the global validation pipe runs with whitelist: true, so an unknown property is stripped silently. Sending the field before the API accepts it would look like it works and record nothing.
2. Frontend — send it when a session exists
reportClientError adds the identifier the session already exposes (useUserContext().user?.accountId), omitting the field entirely when nobody is signed in. Reporting must stay fire-and-forget and must not start depending on user context being loaded — a failure early in startup is exactly the case this reporting exists to catch, and it has to keep working there.
Constraints worth stating up front
- The value is client-supplied, so it is a diagnostic hint and nothing more. The endpoint is deliberately unauthenticated ("the errors worth catching happen before or without a session"), so anyone can post any number. It must never be used for authorization, ownership checks, or anything but correlation — and whoever reads these logs should know that.
- Optional by definition. Errors before sign-in are a large part of what this catches; those reports simply carry no account.
- Keep the existing field limits and sanitizing. Validate as a number so a free-text value cannot ride in on this field.
Related
The failure class that prompted this is #1226 (asset misses served as the app shell and cached immutably), which is about the cause. This issue is only about being able to answer who was affected.
What happens
A client error report carries
message,type,stack,routeandversion— but nothing that identifies the account that hit the failure, even when the customer is signed in and the app already knows it.The resulting log line looks like this:
So the record answers what broke and where, but never who it happened to.
Why it matters
When a customer reports "I can't buy anything, it keeps showing something went wrong", there is no way to look up whether that customer's failure is among the recorded ones — nor how often it hit them, nor whether it stopped.
This is not hypothetical. A support report was checked against the logs today: the failures were in there, but tying them to the reporting customer took a chain of indirect evidence — correlating the time the support entry was updated, resolving client IPs out of trace data, and observing that the customer produced no purchase requests at all during the affected window because the page never loaded far enough. The conclusion stayed circumstantial, and it only worked because the incident happened to be recent and narrow. For anything older, or during a busy period, the same question cannot be answered at all.
An account id in the report turns that reconstruction into a single lookup.
Proposed change
1. API — accept and record the field (must come first)
CreateClientErrorDtogains an optional numeric account id, andClientErrorServicelogs it as its ownkey=valuefield so it stays queryable:This step is a prerequisite, not a nicety: the global validation pipe runs with
whitelist: true, so an unknown property is stripped silently. Sending the field before the API accepts it would look like it works and record nothing.2. Frontend — send it when a session exists
reportClientErroradds the identifier the session already exposes (useUserContext().user?.accountId), omitting the field entirely when nobody is signed in. Reporting must stay fire-and-forget and must not start depending on user context being loaded — a failure early in startup is exactly the case this reporting exists to catch, and it has to keep working there.Constraints worth stating up front
Related
The failure class that prompted this is #1226 (asset misses served as the app shell and cached immutably), which is about the cause. This issue is only about being able to answer who was affected.