1515import java .util .Optional ;
1616
1717public class FgaError extends ApiException {
18+ /**
19+ * Shared ObjectMapper instance for parsing error responses.
20+ * ObjectMapper is thread-safe for read operations (parsing JSON).
21+ * This instance is shared across all error classes to reduce memory overhead.
22+ */
1823 private static final ObjectMapper ERROR_MAPPER = new ObjectMapper ();
1924
2025 private String method = null ;
@@ -27,7 +32,14 @@ public class FgaError extends ApiException {
2732 private String apiErrorMessage = null ;
2833 private String operationName = null ;
2934 private String retryAfterHeader = null ;
30- private Map <String , Object > metadata = null ;
35+
36+ /**
37+ * Metadata map for additional error context.
38+ * <p>
39+ * Note: Error instances follow a single-threaded lifecycle (create → populate → throw → catch).
40+ * They are not shared between threads, so thread-safety is not required.
41+ */
42+ private final Map <String , Object > metadata = new HashMap <>();
3143
3244 public FgaError (String message , Throwable cause , int code , HttpHeaders responseHeaders , String responseBody ) {
3345 super (message , cause , code , responseHeaders , responseBody );
@@ -176,6 +188,11 @@ public void setMethod(String method) {
176188 this .method = method ;
177189 }
178190
191+ /**
192+ * Gets the HTTP method used for the request that caused this error.
193+ *
194+ * @return The HTTP method (e.g., "GET", "POST"), or null if not set
195+ */
179196 public String getMethod () {
180197 return method ;
181198 }
@@ -184,6 +201,11 @@ public void setRequestUrl(String requestUrl) {
184201 this .requestUrl = requestUrl ;
185202 }
186203
204+ /**
205+ * Gets the API URL for the request that caused this error.
206+ *
207+ * @return The request URL, or null if not set
208+ */
187209 public String getRequestUrl () {
188210 return requestUrl ;
189211 }
@@ -192,6 +214,11 @@ public void setClientId(String clientId) {
192214 this .clientId = clientId ;
193215 }
194216
217+ /**
218+ * Gets the OAuth2 client ID used in the request, if client credentials authentication was used.
219+ *
220+ * @return The client ID, or null if not using client credentials or not set
221+ */
195222 public String getClientId () {
196223 return clientId ;
197224 }
@@ -200,6 +227,11 @@ public void setAudience(String audience) {
200227 this .audience = audience ;
201228 }
202229
230+ /**
231+ * Gets the OAuth2 audience used in the request, if client credentials authentication was used.
232+ *
233+ * @return The audience, or null if not using client credentials or not set
234+ */
203235 public String getAudience () {
204236 return audience ;
205237 }
@@ -208,6 +240,11 @@ public void setGrantType(String grantType) {
208240 this .grantType = grantType ;
209241 }
210242
243+ /**
244+ * Gets the OAuth2 grant type used in the request.
245+ *
246+ * @return The grant type, or null if not set
247+ */
211248 public String getGrantType () {
212249 return grantType ;
213250 }
@@ -216,6 +253,11 @@ public void setRequestId(String requestId) {
216253 this .requestId = requestId ;
217254 }
218255
256+ /**
257+ * Gets the request ID from the response headers, useful for debugging and support.
258+ *
259+ * @return The request ID (from X-Request-Id header), or null if not present
260+ */
219261 public String getRequestId () {
220262 return requestId ;
221263 }
@@ -224,6 +266,11 @@ public void setApiErrorCode(String apiErrorCode) {
224266 this .apiErrorCode = apiErrorCode ;
225267 }
226268
269+ /**
270+ * Gets the error code returned by the API in the response body.
271+ *
272+ * @return The API error code, or null if not available in the response
273+ */
227274 public String getApiErrorCode () {
228275 return apiErrorCode ;
229276 }
@@ -241,6 +288,11 @@ public void setRetryAfterHeader(String retryAfterHeader) {
241288 this .retryAfterHeader = retryAfterHeader ;
242289 }
243290
291+ /**
292+ * Gets the Retry-After header value from rate limit responses.
293+ *
294+ * @return The Retry-After header value (in seconds or HTTP date), or null if not present
295+ */
244296 public String getRetryAfterHeader () {
245297 return retryAfterHeader ;
246298 }
@@ -249,6 +301,11 @@ public void setApiErrorMessage(String apiErrorMessage) {
249301 this .apiErrorMessage = apiErrorMessage ;
250302 }
251303
304+ /**
305+ * Gets the error message parsed from the API response body.
306+ *
307+ * @return The API error message, or null if not available in the response
308+ */
252309 public String getApiErrorMessage () {
253310 return apiErrorMessage ;
254311 }
@@ -257,25 +314,38 @@ public void setOperationName(String operationName) {
257314 this .operationName = operationName ;
258315 }
259316
317+ /**
318+ * Gets the operation name that resulted in this error.
319+ *
320+ * @return The operation name (e.g., "check", "write"), or null if not set
321+ */
260322 public String getOperationName () {
261323 return operationName ;
262324 }
263325
264- public void setMetadata (Map <String , Object > metadata ) {
265- this .metadata = metadata ;
266- }
267-
326+ /**
327+ * Gets the metadata map containing additional error context.
328+ *
329+ * @return A map of metadata key-value pairs (never null)
330+ */
268331 public Map <String , Object > getMetadata () {
269- if (metadata == null ) {
270- metadata = new HashMap <>();
271- }
272332 return metadata ;
273333 }
274334
275335 public void addMetadata (String key , Object value ) {
276336 getMetadata ().put (key , value );
277337 }
278338
339+ /**
340+ * Provides access to the shared ObjectMapper for subclasses.
341+ * This mapper is thread-safe for read operations.
342+ *
343+ * @return The shared ObjectMapper instance
344+ */
345+ protected static ObjectMapper getErrorMapper () {
346+ return ERROR_MAPPER ;
347+ }
348+
279349 /**
280350 * Override getMessage() to return the actual API error message
281351 * instead of the generic operation name.
0 commit comments