Enhanced Exception handling #1
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What This Code Does
This is a catch block that intercepts any Exception thrown during proxy connection operations and
transforms it into a more specific ServerError type.
The when Expression Logic
The when expression acts like a sophisticated error classifier:
val connectionError = when (exception) {
is ServerError -> exception // Already structured, pass through
is java.net.ConnectException -> ServerError.ConnectionError.GraphConnectionFailure(graph.toString(),
exception)
is java.net.SocketTimeoutException -> ServerError.ConnectionError.ConnectionTimeout(30000L)
is java.io.IOException -> ServerError.ConnectionError.ConnectionClosed(exception.message)
else -> ServerError.ConnectionError.AcceptFailure(exception)
}
Each Case Explained:
- If it's already one of our structured errors, don't double-wrap it
- Just pass it through unchanged
- Network connection was refused (e.g., Neo4j server not running)
- Creates GraphConnectionFailure with the graph URL for context
- Original exception preserved as cause
- Connection took too long to establish
- Creates ConnectionTimeout with a hardcoded 30-second timeout
- Provides clear timeout context
- Generic I/O error (connection reset, broken pipe, etc.)
- Creates ConnectionClosed with the error message
- Covers unexpected connection drops
- Catch-all for any other unexpected exceptions
- Wraps unknown errors as connection accept failures
- Ensures no exception goes unhandled
Benefits of This Approach
Before (Generic Handling):
} catch (exception: Exception) {
LOGGER.error("Proxy connection failure", exception)
}
After (Structured Handling):
} catch (exception: Exception) {
val connectionError = when (exception) { /* ... */ }
LOGGER.error("Proxy connection failure: {}", connectionError.message, connectionError)
}
Real-World Example
If Neo4j is down, instead of:
ERROR: Proxy connection failure java.net.ConnectException: Connection refused
You get:
ERROR: Proxy connection failure: Failed to connect to graph at 'bolt://localhost:7687'
This immediately tells operators:
This pattern transforms low-level technical exceptions into business-meaningful error descriptions that
help with debugging, monitoring, and automated recovery.