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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions