feat: expose structured API error data in RazorpayException - #361
Merged
Conversation
RazorpayException now stores the full error JSON object and HTTP status code from API responses, accessible via getErrorResponse() and getStatusCode(). The existing string message (code:description) is preserved for backward compatibility. Also adds JSONException guards in processResponse, processCollectionResponse, and processDeleteResponse to handle non-JSON responses (e.g. 503 HTML) gracefully instead of crashing with an unhandled RuntimeException. Addresses the Coursera ask pending since 2020 — merchants can now detect specific error types by checking the code field directly instead of parsing a concatenated string, and access all fields (source, step, reason, metadata, field) for their error handling logic. Co-authored-by: ankitdas13 <ankit.das@razorpay.com>
… catches P0: Mark errorResponse as transient to prevent NotSerializableException in Spring apps and other serialization contexts. JSONObject is not Serializable and Exception implements Serializable. P1: Add safe convenience getters (getCode, getDescription, getField, getReason, getSource, getStep) that return null for missing fields instead of throwing JSONException. This prevents crashes when merchants access optional fields on errors that don't have them (e.g. 401 auth errors have no 'field' or 'step'). Fix: Pass statusCode to RazorpayException in all 3 IOException catch blocks in ApiClient for consistency with JSONException catches. Co-authored-by: ankitdas13 <ankit.das@razorpay.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
The Java SDK discards the Razorpay API's structured error JSON and flattens it to a
code:descriptionstring. Merchants like Coursera have to parse this string to detect error types — fragile when the description itself contains:.This has been pending since 2020. Multiple Coursera production incidents in 2026 were harder to diagnose because of this limitation.
Changes
RazorpayException.javaJSONObject errorResponseandint statusCodefieldsgetErrorResponse()— returns the full error JSON object (code,description,source,step,reason,metadata,field)getStatusCode()— returns the HTTP status code(String, JSONObject, int)and(String, int)null/0)ApiClient.javathrowException()now passes the full error JSON object + status code toRazorpayExceptionthrowServerException()now passes the status codeJSONExceptioncatch inprocessResponse(),processCollectionResponse(),processDeleteResponse()— handles non-JSON responses (e.g. 503 HTML) gracefully instead of crashing with an unhandledRuntimeExceptionresponseJsonhandling inthrowException()Usage
Backward Compatibility
code:description) is unchangednull/0when using old constructorsTesting
RazorpayExceptionTest.javacovering: structured error response, status code, backward-compatible message, server exception status code, non-JSON response handling, constructor defaultsContext
ApiClient.throwException(ApiClient.java:228)appeared explicitly in Coursera's production error reports