Programming · free software · the open webSubscribe via RSS

How Do You Test an API Error Without Leaking Internals?

From the earlier reference collection. Read the current software blog.

Trigger a controlled failure and check that the public response is useful while omitting stack traces, secrets, and implementation details.

Create a controlled failure

Use a test double or a deliberately invalid but safe input to make one dependency fail in a predictable way. For example, have a fake storage adapter raise a known exception while handling a request for a harmless test record. Keep the failure isolated so the test is checking the API’s error boundary rather than an unrelated network or database outage.

Exercise the same route and serialization path used by ordinary requests. A unit test that only inspects an exception handler may miss a framework layer that adds debug details or changes the response body. Run the request in the production-like configuration intended for public use, with debug output disabled.

Check the public contract

Assert the documented status code, content type, and safe error shape. The response should give a caller enough information to understand that the request failed and, where appropriate, whether retrying may help. It should not expose a traceback, source file path, query text, internal host name, or raw exception message.

Use a distinctive sentinel in the test exception, such as PRIVATE_TEST_MARKER_42, and assert that it does not occur anywhere in the response body or headers. Include a fake credential-like value in the dependency context if the code could accidentally echo configuration. This makes the leakage check concrete without using real secrets.

Inspect logs separately

Public responses and internal diagnostics have different audiences. The API may log a request identifier and a sanitized error category for operators, but tests should ensure that sensitive values are redacted there too if the logging path handles them. Do not require the public body to contain an internal exception merely because a developer needs debugging context.

Check headers as well as JSON fields. Some systems accidentally include infrastructure details in server banners or diagnostic headers even when the body is generic. Search the complete captured response for the sentinel and other test-only private strings.

Keep the test maintainable

Prefer assertions about forbidden disclosures and the stable public contract over matching every character of an error message. Copy editing can then improve wording without weakening privacy. A separate test can verify that the failure is logged with an appropriate correlation identifier if that behavior is part of the service contract.

The resulting check demonstrates two things together: the caller gets a clear, predictable failure response, and implementation details remain behind the API boundary. Use only synthetic values in fixtures, so a failure report itself cannot reveal production credentials or personal data.

Suggest a correction · All posts