How do I log errors without logging personal data?
Log minimal references and codes, not full contents. Record a request id or an order id, redact personal fields before anything is written, and never log the whole request or user object. Logging less data, and less identifying data, is what GDPR data minimisation (Art. 5(1)(c)) is about. Treat an identifier that points to a person as personal data too, and keep it to what you actually need to investigate.
Log references, not contents
Record the minimal identifier you need to investigate (a request id, an order id), not the email, address, or full body. Even an identifier can be personal data when it points to a person, so log only enough to trace the issue, not the contents behind it.
Redact at the boundary
Put redaction in the logger or a serializer so personal fields are stripped before anything is written, rather than relying on every call site to remember. One place to get right beats dozens.
Never log the whole object
Avoid logging the entire request, user, or error context when it carries personal data. Log the specific fields you need, so a convenient one-liner does not quietly copy a customer's data into your logs.
try { await createOrder(req)-} catch (e) { logger.error("checkout failed", { body: req }) }+} catch (e) { logger.error("checkout failed", { orderId: req.orderId, code: e.code }) }The log keeps the reference and the error code you need to investigate, without copying the customer's contact and address details into it.