{"record":{"id":"4e9dad75d1de9086","repo":"tursodatabase/turso","slug":"resultset-closed","errorCode":null,"errorMessage":"ResultSet closed","messagePattern":"ResultSet closed","errorType":"exception","errorClass":"java.sql.SQLException","httpStatus":null,"severity":"error","filePath":"bindings/java/src/main/java/tech/turso/core/TursoResultSet.java","lineNumber":140,"sourceCode":"\n  /** Gets the current row number (0-based, 0 means before first row). */\n  public int getRow() {\n    return row;\n  }\n\n  /**\n   * Checks the status of the result set.\n   *\n   * @return true if it's ready to iterate over the result set; false otherwise.\n   */\n  public boolean isOpen() {\n    return open;\n  }\n\n  /** @throws SQLException if not {@link #open} */\n  public void checkOpen() throws SQLException {\n    if (!open) {\n      throw new SQLException(\"ResultSet closed\");\n    }\n  }\n\n  public void close() throws SQLException {\n    this.open = false;\n  }\n\n  public Object get(String columnName) throws SQLException {\n    final int columnsLength = this.columnNames.length;\n    for (int i = 0; i < columnsLength; i++) {\n      if (this.columnNames[i].equals(columnName)) {\n        return get(i + 1);\n      }\n    }\n\n    throw new SQLException(\"column name \" + columnName + \" not found\");\n  }\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/java/src/main/java/tech/turso/core/TursoResultSet.java#L122-L158","documentation":"checkOpen() is the shared guard that most ResultSet operations call before doing work; it throws 'ResultSet closed' when the open flag is false. The flag flips on close() and on an invalid-state step inside next(). Because the class uses three different wordings for this same condition (also 'The result set is not open' and 'The resultSet is not open'), callers must not branch on exact message text.","triggerScenarios":"Any accessor that routes through checkOpen() invoked after close(), or after next() auto-closed the set following an invalid step result.","commonSituations":"try-with-resources closing earlier than expected in nested scopes; helper utilities closing result sets they do not own; code continuing after a swallowed step error.","solutions":["Check isOpen() before accessors whenever the set is shared or its lifecycle is not local","Make one component the sole owner of close()","After any step error, discard the set instead of calling further methods on it"],"exampleFix":"// before\nObject v = rs.get(1); // after rs was closed elsewhere -> 'ResultSet closed'\n\n// after\nif (!rs.isOpen()) {\n  throw new IllegalStateException(\"result set already consumed\");\n}\nObject v = rs.get(1);","handlingStrategy":"validation","validationCode":"if (!rs.isOpen()) {\n  return; // or throw your own domain-specific exception\n}\nObject value = rs.get(1);","typeGuard":null,"tryCatchPattern":"try {\n  return rs.get(1);\n} catch (SQLException e) {\n  // same closed-set condition as the other two message variants; never match on wording\n  throw new IllegalStateException(\"result set already closed\", e);\n}","preventionTips":["Never read columns outside a while (rs.next()) block that returned true","After any SQLException from next(), consider the set closed and stop using it","The class has three wordings for this condition — branch on state, not message text"],"tags":["java","jdbc","result-set","resource-lifecycle"],"backgroundTag":"result-set-closed","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}