The GQLDB Java driver reports all failures through a single base exception, GqldbException. Rather than a wide hierarchy of catchable subclasses, the driver exposes a small set of public exception types and distinguishes the remaining failure modes through an error code and message.
The public API defines four exception types:
| Exception | Thrown when |
|---|---|
GqldbException | Base type for every driver failure. Server errors arrive here with a [code]-prefixed message; read the code via getCode(). |
GraphNotFoundException | An operation targets a graph that does not exist (e.g. getGraphInfo). |
TransactionNotFoundException | A transaction operation runs with no active transaction. |
EmptyQueryException | A query string is empty. |
All three specific types extend GqldbException, so a single catch (GqldbException e) still handles everything; catch a subtype first only when you want to react to that case by class rather than by inspecting the message.
NOTENote: Earlier releases defined many finer-grained internal types (for connection, login, session, etc.). Those were never part of the public API and have been removed — the conditions they described now surface as a plain
GqldbException. Always catchGqldbExceptionand branch ongetCode()/getMessage()when you need to tell those cases apart.
Javaimport com.gqldb.GqldbException; public class GqldbException extends RuntimeException { private final int code; public int getCode(); public String getMessage(); public Throwable getCause(); }
Every GqldbException carries:
message: Human-readable error descriptioncode: Numeric error code (0 when unset)cause: Original exception that caused this error (if applicable)EmptyQueryException extends GqldbException and is thrown when a query string is empty. Because it is a public subclass, you may catch it directly before the base type.
The driver surfaces the following conditions as a GqldbException. Inspect getMessage() (or getCode()) to react to a specific one.
| Condition | Description |
|---|---|
| No hosts configured | The client was built without any hosts |
| Invalid timeout | An invalid timeout value was specified |
Javaimport com.gqldb.*; try { GqldbConfig config = GqldbConfig.builder() .hosts() // Empty hosts .build(); } catch (GqldbException e) { System.err.println("You must configure at least one host: " + e.getMessage()); }
| Condition | Description |
|---|---|
| No connection | No connection available |
| Connection closed | Connection has been closed |
| Connection failed | Failed to establish a connection |
| All hosts failed | All configured hosts are unreachable |
Javapublic boolean connectWithRetry(GqldbClient client, int maxRetries) { for (int i = 0; i < maxRetries; i++) { try { client.login("user", "pass"); return true; } catch (GqldbException e) { System.out.println("Connection attempt " + (i + 1) + " failed: " + e.getMessage()); try { Thread.sleep(1000 * (i + 1)); // Exponential backoff } catch (InterruptedException ie) { Thread.currentThread().interrupt(); return false; } } } return false; }
| Condition | Description |
|---|---|
| Not logged in | Operation requires authentication |
| Login failed | Login failed (wrong credentials) |
| Session expired | Session has expired |
Javapublic void ensureLoggedIn(GqldbClient client) { try { client.gql("MATCH (n) RETURN count(n)"); } catch (GqldbException e) { System.out.println("Session issue, re-authenticating: " + e.getMessage()); client.login("user", "pass"); } }
| Condition | Description |
|---|---|
| Transaction not found | No active transaction (TransactionNotFoundException) |
| Transaction failed | Transaction operation failed (base GqldbException) |
TransactionNotFoundException is a public subclass, so you can catch it directly before the base type:
Javapublic void safeTransaction(GqldbClient client, GqldbClient.TransactionFunction<?> fn) { try { client.withTransaction("myGraph", fn); } catch (TransactionNotFoundException e) { System.err.println("No active transaction (it may have timed out)"); } catch (GqldbException e) { System.err.println("Transaction failed: " + e.getMessage()); } }
| Condition | Description |
|---|---|
| Query failed | Query execution failed |
| Empty query | Query string is empty (EmptyQueryException) |
Javapublic Response executeQuery(GqldbClient client, String query) { try { return client.gql(query); } catch (EmptyQueryException e) { // EmptyQueryException is a public subclass — catch it before the base type. System.err.println("Query cannot be empty"); } catch (GqldbException e) { System.err.println("Query failed: " + e.getMessage()); } return null; }
| Condition | Description |
|---|---|
| Graph not found | Graph does not exist (GraphNotFoundException) |
| Graph exists | Graph already exists (base GqldbException from the server) |
getGraphInfo throws GraphNotFoundException — a public subclass — when the graph is missing, so you can catch it directly:
Javapublic void ensureGraph(GqldbClient client, String graphName) { try { client.getGraphInfo(graphName); System.out.println("Graph " + graphName + " exists"); } catch (GraphNotFoundException e) { // Graph not found — try to create it. try { client.createGraph(graphName); System.out.println("Created graph " + graphName); } catch (GqldbException e2) { // Race condition: another process created it first. System.out.println("Graph " + graphName + " already exists: " + e2.getMessage()); } } }
Javapublic void handleAllErrors(GqldbClient client) { try { client.login("user", "pass"); client.gql("MATCH (n) RETURN n"); } catch (GqldbException e) { // All driver failures System.err.println("GQLDB Error [code " + e.getCode() + "]: " + e.getMessage()); if (e.getCause() != null) { System.err.println("Caused by: " + e.getCause()); } } catch (Exception e) { // Other (non-driver) exceptions System.err.println("Unexpected error: " + e.getMessage()); } }
Because failure modes are distinguished by code/message rather than by type, drive retry decisions with a predicate over GqldbException:
Javapublic <T> T withRetry(Supplier<T> operation, int maxRetries, Predicate<GqldbException> isRetryable) { GqldbException lastError = null; for (int attempt = 1; attempt <= maxRetries; attempt++) { try { return operation.get(); } catch (GqldbException e) { lastError = e; if (!isRetryable.test(e) || attempt == maxRetries) { throw e; } System.out.println("Attempt " + attempt + " failed, retrying..."); try { Thread.sleep(1000 * attempt); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw e; } } } throw new RuntimeException("Should not reach here", lastError); } // Usage: retry on transient connection errors Response result = withRetry( () -> client.gql("MATCH (n) RETURN n LIMIT 100"), 3, e -> e.getMessage() != null && e.getMessage().contains("connection") );
Javapublic Response getDataWithFallback(GqldbClient client) { try { // Try the main query return client.gql("MATCH (n:User) RETURN n"); } catch (GqldbException e) { if (e.getMessage() != null && e.getMessage().contains("timeout")) { // Fall back to a simpler query System.out.println("Full query timed out, using limited query"); return client.gql("MATCH (n:User) RETURN n LIMIT 100"); } throw e; } }
Javapublic void transactionWithCleanup(GqldbClient client) { Transaction tx = null; try { tx = client.beginTransaction("myGraph"); client.gqlInTransaction("INSERT ...", tx.getId()); client.gqlInTransaction("INSERT ...", tx.getId()); client.commit(tx.getId()); tx = null; // Transaction completed } finally { if (tx != null) { // Transaction was started but not committed try { client.rollback(tx.getId()); } catch (Exception rollbackError) { System.err.println("Rollback failed: " + rollbackError.getMessage()); } } } }
Javaimport com.gqldb.*; public class ErrorHandlingExample { public static void main(String[] args) { GqldbConfig config = GqldbConfig.builder() .hosts("localhost:9000") .timeout(30) .build(); try (GqldbClient client = new GqldbClient(config)) { // Login with error handling try { client.login("admin", "password"); System.out.println("Logged in successfully"); } catch (GqldbException e) { System.err.println("Login failed: " + e.getMessage()); System.exit(1); } // Ensure graph exists String graphName = "errorDemo"; try { client.getGraphInfo(graphName); } catch (GqldbException e) { client.createGraph(graphName); System.out.println("Created graph"); } client.useGraph(graphName); // Transaction with error handling try { client.withTransaction(graphName, txId -> { client.gqlInTransaction( "INSERT (n:User {_id: \"u1\", name: \"Alice\"})", txId ); // Simulate potential error if (Math.random() < 0.3) { throw new RuntimeException("Random failure for demo"); } return null; }); System.out.println("Transaction succeeded"); } catch (GqldbException e) { System.err.println("Transaction failed, changes rolled back: " + e.getMessage()); } catch (RuntimeException e) { System.err.println("Error during transaction: " + e.getMessage()); } // Query with timeout handling try { QueryConfig queryConfig = new QueryConfig(); queryConfig.setTimeout(5); // 5 seconds Response response = client.gql("MATCH (n) RETURN n", queryConfig); System.out.println("Found " + response.getRowCount() + " results"); } catch (GqldbException e) { if (e.getMessage() != null && e.getMessage().contains("timeout")) { System.out.println("Query timed out, trying with limit"); Response limited = client.gql("MATCH (n) RETURN n LIMIT 10"); System.out.println("Found " + limited.getRowCount() + " results (limited)"); } else { System.err.println("Query error: " + e.getMessage()); } } // Cleanup client.dropGraph(graphName, true); } catch (GqldbException e) { // Catch-all for unexpected errors System.err.println("GQLDB Error [code " + e.getCode() + "]: " + e.getMessage()); if (e.getCause() != null) { System.err.println("Root cause: " + e.getCause().getMessage()); } System.exit(1); } System.out.println("Client closed"); } }