Strong typed API for synchronous TDLib method execution in Java interface

`Client.execute` in Java interface is now strongly typed: returned TDLib object type depends on the return type defined in the corresponding Function class.

When TDLib error is occurred, method now throws `Client.ExecutionError`.

This change adds compile-time protection against return type change and allows using this pattern:

```
try {
  TdApi.SpecificReturnType result = Client.execute(function);
  // work with strongly typed resultl without casting and type checks
} catch (Client.ExecutionError error) {
  // Handle error
}
```
This commit is contained in:
Vyacheslav 2023-10-25 00:52:34 +06:00 committed by Aliaksei Levin
parent c031818156
commit dd77e4628f
1 changed files with 29 additions and 2 deletions

View File

@ -62,6 +62,24 @@ public final class Client {
void onLogMessage(int verbosityLevel, String message);
}
/**
* Exception class thrown when TDLib error occurred while performing {@link #execute(TdApi.Function)}.
*/
public static class ExecutionError extends Throwable {
/**
* Original TDLib error occurred when performing one of the synchronous functions.
*/
public final TdApi.Error error;
/**
* @param error TDLib error occurred while performing {@link #execute(TdApi.Function)}.
*/
ExecutionError (TdApi.Error error) {
super(error.code + ": " + error.message);
this.error = error;
}
}
/**
* Sends a request to the TDLib.
*
@ -102,8 +120,17 @@ public final class Client {
* @return request result.
* @throws NullPointerException if query is null.
*/
public static TdApi.Object execute(TdApi.Function query) {
return nativeClientExecute(query);
public static <T extends TdApi.Object> T execute(TdApi.Function<T> query) throws ExecutionError {
TdApi.Object object = nativeClientExecute(query);
if (object instanceof TdApi.Error) {
throw new ExecutionError((TdApi.Error) object);
}
if (object == null) {
// unreachable
throw new NullPointerException();
}
//noinspection unchecked
return (T) object;
}
/**