Checklist
Description
For checks that fail inside clientBatchCheck, the returned ClientBatchCheckClientResponse has statusCode, headers and rawResponse set to null. getStatusCode() throws NullPointerException because it unboxes the null Integer.
The constructor only copies error metadata when throwable instanceof FgaError:
|
} else if (throwable instanceof FgaError) { |
|
FgaError error = (FgaError) throwable; |
|
this.statusCode = error.getStatusCode(); |
|
this.headers = error.getResponseHeaders().map(); |
|
this.rawResponse = error.getResponseData(); |
|
} else { |
|
// Should be unreachable, but required for type completion |
|
this.statusCode = null; |
|
this.headers = null; |
|
this.rawResponse = null; |
|
} |
The throwable it receives is the CompletionException from the check future, with the FgaError as its cause, so that branch never runs:
|
public int getStatusCode() { |
|
return statusCode; |
|
} |
Expectation
For a failed check, getStatusCode(), getHeaders() and getRawResponse() return the status code, headers and body of the error response.
Reproduction
Reproduces consistently. Any error status (400/404/500) behaves the same.
import com.sun.net.httpserver.HttpServer;
import dev.openfga.sdk.api.client.OpenFgaClient;
import dev.openfga.sdk.api.client.model.ClientCheckRequest;
import dev.openfga.sdk.api.configuration.ClientConfiguration;
import dev.openfga.sdk.api.configuration.Credentials;
import java.net.InetSocketAddress;
import java.util.List;
public class IssueRepro {
public static void main(String[] args) throws Exception {
var server = HttpServer.create(new InetSocketAddress(8089), 0);
server.createContext("/", exchange -> {
byte[] body = "{\"code\":\"validation_error\",\"message\":\"test\"}".getBytes();
exchange.sendResponseHeaders(400, body.length);
exchange.getResponseBody().write(body);
exchange.close();
});
server.start();
var fga = new OpenFgaClient(new ClientConfiguration()
.apiUrl("http://localhost:8089")
.storeId("01YCP46JKYM8FJCQ37NMBYHE5X")
.credentials(new Credentials()));
var item = fga.clientBatchCheck(List.of(new ClientCheckRequest()
.user("user:anne")
.relation("reader")
._object("document:1")))
.get()
.get(0);
System.out.println(item.getThrowable()); // CompletionException, cause FgaApiValidationError
System.out.println(item.getRawResponse()); // null
System.out.println(item.getStatusCode()); // NullPointerException
}
}
OpenFGA SDK version
v0.9.11
OpenFGA version
n/a (reproduced with the stub server above; any error response triggers it)
SDK Configuration
new ClientConfiguration().apiUrl(...).storeId(...).credentials(new Credentials())
Logs
java.util.concurrent.CompletionException: dev.openfga.sdk.errors.FgaApiValidationError: [check] HTTP 400 test (validation_error)
null
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because "this.statusCode" is null
at dev.openfga.sdk.api.client.model.ClientBatchCheckClientResponse.getStatusCode(ClientBatchCheckClientResponse.java:72)
at IssueRepro.main(IssueRepro.java:34)
References
No response
Checklist
Description
For checks that fail inside
clientBatchCheck, the returnedClientBatchCheckClientResponsehasstatusCode,headersandrawResponseset to null.getStatusCode()throwsNullPointerExceptionbecause it unboxes the nullInteger.The constructor only copies error metadata when
throwable instanceof FgaError:java-sdk/src/main/java/dev/openfga/sdk/api/client/model/ClientBatchCheckClientResponse.java
Lines 27 to 37 in 37317f2
The throwable it receives is the
CompletionExceptionfrom the check future, with theFgaErroras its cause, so that branch never runs:java-sdk/src/main/java/dev/openfga/sdk/api/client/model/ClientBatchCheckClientResponse.java
Lines 71 to 73 in 37317f2
Expectation
For a failed check,
getStatusCode(),getHeaders()andgetRawResponse()return the status code, headers and body of the error response.Reproduction
Reproduces consistently. Any error status (400/404/500) behaves the same.
OpenFGA SDK version
v0.9.11
OpenFGA version
n/a (reproduced with the stub server above; any error response triggers it)
SDK Configuration
new ClientConfiguration().apiUrl(...).storeId(...).credentials(new Credentials())Logs
References
No response