Skip to content

Commit

Permalink
Document how to send response errors (#561)
Browse files Browse the repository at this point in the history
Co-authored-by: Vladimir Piskarev <pisv@1c.ru>
  • Loading branch information
fredg1 and pisv authored Jul 7, 2021
1 parent 7512f5d commit a352a4d
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions documentation/jsonrpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,29 @@ You always work with two `Endpoints`. Usually one of the endpoints, a `RemoteEnd

# Requests

For requests the story is slightly more complicated. When a request message comes in, the `RemoteEndpoint` tracks the request `id` and invokes `request` on the local endpoint. In addition it adds completion stage to the returned `CompletableFuture`, that translates the result into a JSON RPC response message.
For requests, the story is slightly more complicated. When a request message comes in, the `RemoteEndpoint` tracks the request `id` and invokes `request` on the local endpoint. In addition it adds completion stage to the returned `CompletableFuture`, that translates the result into a JSON RPC response message.

For the other direction, if the implementation calls request on the RemoteEndpoint, the message is send and tracked locally.
The returned `CompletableFuture` will complete once a corresponsing result message is received.

## Response Errors

The receiver of a request always needs to return a response message to conform to the JSON RPC specification. In case the result value cannot be provided in a response because of an error, the `error` property of the `ResponseMessage` must be set to a `ResponseError` describing the failure.

This can be done by throwing a `ResponseErrorException` from the request message handler in a local endpoint. The exception carries a `ResponseError` to attach to the response. The `RemoteEndpoint` will handle the exception and send a response message with the attached error object.

For example:
```java
@Override
public CompletableFuture<Object> shutdown() {
if (!isInitialized()) {
ResponseError error = new ResponseError(ResponseErrorCode.serverNotInitialized, "Server was not initialized", null);
throw new ResponseErrorException(error);
}
return doShutdown();
}
```

# Cancelling Requests

The LSP defines an extension to the JSON RPC, that allows to cancel requests. It is done through a special notification message, that contains the request id that should be cancelled. If you want to cancel a pending request in LSP4J, you can simply call `cancel(true)` on the returned `CompletableFuture`. The `RemoteEndpoint` will send the cancellation notification. If you are implementing a request message, you should return a `CompletableFuture` created through [`CompletebleFutures.computeAsync`] (../org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/CompletableFutures.java#L24). It accepts a lambda that is provided with a `CancelChecker`, which you need to ask `checkCanceled` and which will throw a `CancellationException` in case the request got canceled.
Expand Down Expand Up @@ -113,4 +131,3 @@ public interface NamingExample {
CompletableFuture<?> yetanothername();
}
```

0 comments on commit a352a4d

Please sign in to comment.