Skip to content

The /database endpoint returns HTTP 200 on connection failure, should return 500 #238

@schneems

Description

@schneems

Problem

The /database endpoint in GettingStartedApplication.java catches all Throwable exceptions and renders an error template with HTTP 200:

@GetMapping("/database")
String database(Map<String, Object> model) {
    try (Connection connection = dataSource.getConnection()) {
        // ...
    } catch (Throwable t) {
        model.put("message", t.getMessage());
        return "error";
    }
}

When the database connection fails (e.g. transient network issue, SSL negotiation failure after a dyno restart), the endpoint returns a 200 OK with the body <p>The connection attempt failed.</p>.

This is a problem because:

  1. curl --fail can't detect the error — it only triggers on HTTP 4xx/5xx status codes, so automated checks that rely on curl --fail silently pass even though the database interaction failed.
  2. The ticks table is never created — since CREATE TABLE IF NOT EXISTS ticks runs inside the same try block, a connection failure means the table doesn't exist, causing downstream SELECT * FROM ticks queries to blow up with ERROR: relation "ticks" does not exist.
  3. Misleading for newcomers — a 200 response suggests success, making transient database issues harder to diagnose.

Suggested Fix

Return an HTTP 500 status on failure so that standard HTTP error detection works:

@GetMapping("/database")
String database(Map<String, Object> model, HttpServletResponse response) {
    try (Connection connection = dataSource.getConnection()) {
        // ... existing logic ...
    } catch (Throwable t) {
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        model.put("message", t.getMessage());
        return "error";
    }
}

Context

Discovered during automated tutorial doc generation where all 17 other language/framework builds passed but java_maven_classic failed. The /database curl silently returned 200 with an error page, so the failure wasn't caught until heroku pg:psql -c "SELECT * FROM ticks" ran and the table didn't exist.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions