DEV Community

Nico Reyes
Nico Reyes

Posted on

I spent 3 hours debugging. Then I found the print statement.

I spent 3 hours debugging. Then I found the print statement.

Wasted Wednesday afternoon tracking down why my API kept returning 500 errors. Turned out someone left a debug print in production that broke the JSON response.

What happened

API endpoint worked fine locally. Deployed to staging, started getting 500s. Error logs said "invalid JSON" but the response looked clean in Postman.

Checked database queries. Fine. Environment variables all set. Request headers valid. Network logs looked normal. Three hours of this.

Found it by accident

Piped the raw response to a file:

curl -s https://api.example.com/users | cat -A
Enter fullscreen mode Exit fullscreen mode

Saw this:

DEBUG: Query took 0.34s$
{"users": [...]}$
Enter fullscreen mode Exit fullscreen mode

Someone left a print statement in the database wrapper. JSON parser choked on the text before the actual JSON.

# The culprit
def fetch_users():
    start = time.time()
    result = db.query("SELECT * FROM users")
    print(f"DEBUG: Query took {time.time() - start:.2f}s")  # โ† This
    return result
Enter fullscreen mode Exit fullscreen mode

Deleted the print statement. Deployed. API worked.

Switched to proper logging

Print statements break JSON responses because they go to stdout. Started using logging instead:

import logging

logger = logging.getLogger(__name__)

def fetch_users():
    start = time.time()
    result = db.query("SELECT * FROM users")
    logger.debug(f"Query took {time.time() - start:.2f}s")
    return result
Enter fullscreen mode Exit fullscreen mode

Logs go to stderr, not stdout. Can filter by level in production (only ERROR/WARN, skip DEBUG).

Added a lint rule that fails CI if it finds print statements outside test files:

# .pylintrc
[MESSAGES CONTROL]
disable=print-statement
Enter fullscreen mode Exit fullscreen mode

Not foolproof but catches most before production.

Response validation helped too

Added JSON schema validation to integration tests. Would've caught the malformed response before deploy:

import jsonschema

def test_users_endpoint():
    response = client.get("/users")
    schema = {"type": "object", "required": ["users"]}
    jsonschema.validate(response.json(), schema)  # Fails if non-JSON
Enter fullscreen mode Exit fullscreen mode

API sets Content-Type: application/json explicitly now. When JSON parsing fails, we log the first 200 chars:

try:
    data = json.loads(response_text)
except json.JSONDecodeError as e:
    logger.error(f"Invalid JSON: {response_text[:200]}")
    raise
Enter fullscreen mode Exit fullscreen mode

Still mad it took 3 hours to find a print statement. Checked database, network, deployment config. Everything except stdout.

Top comments (0)