Diagnostics can become a second data store when they include request bodies and customer notes. “More detailed logging” needs a definition of what may actually be retained.
This experiment neither reads nor collects operational logs. A new synthetic error_record function limits its output fields and tests rejection of unsupported inputs.
Do not accept an exception sentence
The function accepts only code, operation and trace_id. There is no free-form message, request body or arbitrary metadata channel. Rather than accepting everything and attempting pattern removal afterward, the contract narrows what can enter the record. New diagnostics require a deliberate contract change instead of an unreviewed metadata escape hatch.
That choice cannot make an entire program safe. Another handler may print raw exceptions, and infrastructure can independently retain requests. This test verifies one structured-record boundary. Integration still needs inspection of server logs, middleware and external collection settings. A small allowlist is not a completed security audit of the full logging system.
Use fixed error and operation names
Codes are limited to INVALID_INPUT, VERSION_CONFLICT, ACCESS_DENIED and UNEXPECTED. Operations are read, save and preview. A user’s sentence cannot become an operation label. The goal is to identify a category and processing boundary without retaining transaction contents.
Those four categories are not enough for every service. Extend the vocabulary only after deciding what an operator must distinguish. More names do not automatically explain a cause. This example verifies a reproducible classification contract and its constrained output; it does not automatically diagnose an actual outage or derive a correct category from an arbitrary exception.
A trace identifier is not a notes field
trace_id is a bounded ASCII identifier of at most forty characters. It must not be used for an email-like sentence or a private path. A production system should supply an opaque server-generated trace value. The module checks format but neither generates distributed trace identifiers nor propagates them across services.
A caller could intentionally encode company meaning in a syntactically valid identifier; format checks cannot understand and remove that meaning. Call-site rules and review are therefore necessary. Synthetic tests verify rejection of invalid characters and the fixed output fields. This function is not a semantic detector that discovers and removes every kind of personal information.
A retry hint is not an execution command
The record has a retry flag that is true only for UNEXPECTED. This synthetic classification performs no retry. Repeating a save whose outcome is unknown can duplicate a change, so a production retry policy must first consider request identity and reconciliation with committed results.
Treating a conflict or access denial like a transient generic failure can hide the condition that actually needs attention. The example does not suppress errors or convert them into successful empty results. User copy, operator alerts and recovery routes belong to the adopting service. A diagnostic hint must not become independent authorization to execute the business operation again.
Define diagnostic value and retention together
Tests require exactly four output keys and verify that adding a message argument is not accepted. A cross-module test records a review-version conflict using a fixed code while preserving a newer draft. No actual company exception text or request body is used as test material.
Adoption still requires retention duration, viewing permissions, deletion procedures and a route from a trace to a reproducible problem. This module stores and transmits nothing, so it implements none of those operational policies. I share a way to separate the minimum facts needed to distinguish a problem from the original business payload, with the remaining responsibilities visible.