Skip to content

ClientBatchCheckClientResponse.getStatusCode() throws NullPointerException for failed checks #380

Description

@SoulPancake

Checklist

  • I have looked into the README and have not found a suitable solution or answer.
  • I have looked into the documentation and have not found a suitable solution or answer.
  • I have searched the issues and have not found a suitable solution or answer.
  • I have upgraded to the latest version of OpenFGA and the issue still persists.
  • I have searched the Slack community and have not found a suitable solution or answer.
  • I agree to the terms within the OpenFGA Code of Conduct.

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions