Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cherry-pick] Update Dapr CLI + Add HTTP code to DaprException #1020

Merged
merged 7 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ jobs:
GOARCH: amd64
GOPROXY: https://proxy.golang.org
JDK_VER: ${{ matrix.java }}
DAPR_CLI_VER: 1.12.0
DAPR_CLI_VER: 1.13.0-rc.1
DAPR_RUNTIME_VER: 1.13.0-rc.2
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/v1.12.0/install/install.sh
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/v1.13.0-rc.1/install/install.sh
DAPR_CLI_REF:
DAPR_REF:
TOXIPROXY_URL: https://github.com/Shopify/toxiproxy/releases/download/v2.5.0/toxiproxy-server-linux-amd64
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ jobs:
GOARCH: amd64
GOPROXY: https://proxy.golang.org
JDK_VER: ${{ matrix.java }}
DAPR_CLI_VER: 1.12.0
DAPR_CLI_VER: 1.13.0-rc.1
DAPR_RUNTIME_VER: 1.13.0-rc.5
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/v1.12.0/install/install.sh
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/v1.13.0-rc.1/install/install.sh
DAPR_CLI_REF:
DAPR_REF:
steps:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void testInvokeException() throws Exception {
// TODO(artursouza): change this to INTERNAL once runtime is fixed.
assertEquals("UNKNOWN", exception.getErrorCode());
assertNotNull(exception.getMessage());
assertTrue(exception.getMessage().contains("Internal Server Error"));
assertTrue(exception.getMessage().contains("HTTP status code: 500"));
assertTrue(new String(exception.getPayload()).contains("Internal Server Error"));
}
}
Expand Down
15 changes: 6 additions & 9 deletions sdk/src/main/java/io/dapr/client/DaprHttp.java
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,8 @@ private static DaprError parseDaprError(byte[] json) {
try {
return DAPR_ERROR_DETAILS_OBJECT_MAPPER.readValue(json, DaprError.class);
} catch (IOException e) {
throw new DaprException("UNKNOWN", new String(json, StandardCharsets.UTF_8), json);
// Could not parse DaprError. Return null.
return null;
}
}

Expand Down Expand Up @@ -384,17 +385,13 @@ public void onResponse(@NotNull Call call, @NotNull okhttp3.Response response) t
try {
byte[] payload = getBodyBytesOrEmptyArray(response);
DaprError error = parseDaprError(payload);
if ((error != null) && (error.getErrorCode() != null)) {
if (error.getMessage() != null) {
future.completeExceptionally(new DaprException(error, payload));
} else {
future.completeExceptionally(
new DaprException(error.getErrorCode(), "HTTP status code: " + response.code(), payload));
}
if (error != null) {
future.completeExceptionally(new DaprException(error, payload, response.code()));
return;
}

future.completeExceptionally(new DaprException("UNKNOWN", "HTTP status code: " + response.code(), payload));
future.completeExceptionally(
new DaprException("UNKNOWN", "", payload, response.code()));
return;
} catch (DaprException e) {
future.completeExceptionally(e);
Expand Down
92 changes: 71 additions & 21 deletions sdk/src/main/java/io/dapr/exceptions/DaprException.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@

package io.dapr.exceptions;

import com.google.rpc.Status;
import io.grpc.StatusRuntimeException;
import io.grpc.protobuf.StatusProto;
import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
Expand All @@ -30,26 +32,32 @@ public class DaprException extends RuntimeException {
/**
* Dapr's error code for this exception.
*/
private String errorCode;
private final String errorCode;

/**
* The status details for the error.
*/
private DaprErrorDetails errorDetails;
private final DaprErrorDetails errorDetails;

/**
* Optional payload, if the exception came from a response body.
*/
private byte[] payload;
private final byte[] payload;

/**
* Optional HTTP status code, if error happened for an HTTP call (0 if not set).
*/
private final int httpStatusCode;

/**
* New exception from a server-side generated error code and message.
*
* @param daprError Server-side error.
* @param payload Payload containing the error.
* @param payload Optional payload containing the error.
* @param httpStatusCode Optional http Status Code (0 if not set).
*/
public DaprException(DaprError daprError, byte[] payload) {
this(daprError.getErrorCode(), daprError.getMessage(), daprError.getDetails(), payload);
public DaprException(DaprError daprError, byte[] payload, int httpStatusCode) {
this(daprError.getErrorCode(), daprError.getMessage(), daprError.getDetails(), payload, httpStatusCode);
}

/**
Expand Down Expand Up @@ -77,10 +85,11 @@ public DaprException(Throwable exception) {
*
* @param errorCode Client-side error code.
* @param message Client-side error message.
* @param payload Error's raw payload.
* @param payload Optional payload containing the error.
* @param httpStatusCode Optional http Status Code (0 if not set).
*/
public DaprException(String errorCode, String message, byte[] payload) {
this(errorCode, message, DaprErrorDetails.EMPTY_INSTANCE, payload);
public DaprException(String errorCode, String message, byte[] payload, int httpStatusCode) {
this(errorCode, message, DaprErrorDetails.EMPTY_INSTANCE, payload, httpStatusCode);
}

/**
Expand All @@ -89,10 +98,12 @@ public DaprException(String errorCode, String message, byte[] payload) {
* @param errorCode Client-side error code.
* @param message Client-side error message.
* @param errorDetails Details of the error from runtime.
* @param payload Payload containing the error.
* @param payload Optional payload containing the error.
* @param httpStatusCode Optional http Status Code (0 if not set).
*/
public DaprException(String errorCode, String message, List<Map<String, Object>> errorDetails, byte[] payload) {
this(errorCode, message, new DaprErrorDetails(errorDetails), payload);
public DaprException(
String errorCode, String message, List<Map<String, Object>> errorDetails, byte[] payload, int httpStatusCode) {
this(errorCode, message, new DaprErrorDetails(errorDetails), payload, httpStatusCode);
}

/**
Expand All @@ -101,10 +112,29 @@ public DaprException(String errorCode, String message, List<Map<String, Object>>
* @param errorCode Client-side error code.
* @param message Client-side error message.
* @param errorDetails Details of the error from runtime.
* @param payload Payload containing the error.
* @param payload Optional payload containing the error.
*/
public DaprException(String errorCode, String message, DaprErrorDetails errorDetails, byte[] payload) {
super(String.format("%s: %s", errorCode, message));
this(errorCode, message, errorDetails, payload, 0);
}

/**
* New Exception from a client-side generated error code and message.
*
* @param errorCode Client-side error code.
* @param message Client-side error message.
* @param errorDetails Details of the error from runtime.
* @param payload Optional payload containing the error.
* @param httpStatusCode Optional http Status Code (0 if not set).
*/
public DaprException(
String errorCode,
String message,
DaprErrorDetails errorDetails,
byte[] payload,
int httpStatusCode) {
super(buildErrorMessage(errorCode, httpStatusCode, message));
this.httpStatusCode = httpStatusCode;
this.errorCode = errorCode;
this.errorDetails = errorDetails;
this.payload = payload;
Expand All @@ -120,8 +150,11 @@ public DaprException(String errorCode, String message, DaprErrorDetails errorDet
* unknown.)
*/
public DaprException(String errorCode, String message, Throwable cause) {
super(String.format("%s: %s", errorCode, emptyIfNull(message)), cause);
super(buildErrorMessage(errorCode, 0, message), cause);
this.httpStatusCode = 0;
this.errorCode = errorCode;
this.errorDetails = DaprErrorDetails.EMPTY_INSTANCE;
this.payload = null;
}

/**
Expand All @@ -137,7 +170,8 @@ public DaprException(String errorCode, String message, Throwable cause) {
*/
public DaprException(
String errorCode, String message, Throwable cause, DaprErrorDetails errorDetails, byte[] payload) {
super(String.format("%s: %s", errorCode, emptyIfNull(message)), cause);
super(buildErrorMessage(errorCode, 0, message), cause);
this.httpStatusCode = 0;
this.errorCode = errorCode;
this.errorDetails = errorDetails == null ? DaprErrorDetails.EMPTY_INSTANCE : errorDetails;
this.payload = payload;
Expand Down Expand Up @@ -170,6 +204,15 @@ public byte[] getPayload() {
return this.payload == null ? null : this.payload.clone();
}

/**
* Returns the exception's http status code, 0 if not applicable.
*
* @return Http status code (0 if not applicable).
*/
public int getHttpStatusCode() {
return this.httpStatusCode;
}

/**
* Wraps an exception into DaprException (if not already DaprException).
*
Expand Down Expand Up @@ -266,7 +309,7 @@ public static RuntimeException propagate(Throwable exception) {
while (e != null) {
if (e instanceof StatusRuntimeException) {
StatusRuntimeException statusRuntimeException = (StatusRuntimeException) e;
com.google.rpc.Status status = io.grpc.protobuf.StatusProto.fromThrowable(statusRuntimeException);
Status status = StatusProto.fromThrowable(statusRuntimeException);

DaprErrorDetails errorDetails = new DaprErrorDetails(status);

Expand All @@ -289,11 +332,18 @@ public static RuntimeException propagate(Throwable exception) {
return new DaprException(exception);
}

private static String emptyIfNull(String str) {
if (str == null) {
return "";
private static String buildErrorMessage(String errorCode, int httpStatusCode, String message) {
String result = ((errorCode == null) || errorCode.isEmpty()) ? "UNKNOWN: " : errorCode + ": ";
if ((message == null) || message.isEmpty()) {
if (httpStatusCode > 0) {
return result + "HTTP status code: " + httpStatusCode;
}
return result;
}

return str;
if (httpStatusCode > 0) {
return result + message + " (HTTP status code: " + httpStatusCode + ")";
}
return result + message;
}
}
5 changes: 3 additions & 2 deletions sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ public void invokeServiceDaprError() {
});

assertEquals("MYCODE", exception.getErrorCode());
assertEquals("MYCODE: My Message", exception.getMessage());
assertEquals("MYCODE: My Message (HTTP status code: 500)", exception.getMessage());
assertEquals(500, exception.getHttpStatusCode());
}

@Test
Expand Down Expand Up @@ -308,7 +309,7 @@ public void invokeServiceDaprErrorUnknownJSON() {
});

assertEquals("UNKNOWN", exception.getErrorCode());
assertEquals("UNKNOWN: { \"anything\": 7 }", exception.getMessage());
assertEquals("UNKNOWN: HTTP status code: 500", exception.getMessage());
assertEquals("{ \"anything\": 7 }", new String(exception.getPayload()));
}

Expand Down
Loading