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

* Update to 1.13 CLi rc. (#1018)

Signed-off-by: Artur Souza <asouza.pro@gmail.com>

* Add support for HTTP status code in exception. (#1019)

Signed-off-by: Artur Souza <asouza.pro@gmail.com>

---------

Signed-off-by: Artur Souza <asouza.pro@gmail.com>
Co-authored-by: Cassie Coyle <cassie@diagrid.io>
This commit is contained in:
Artur Souza 2024-06-25 14:52:47 -07:00 committed by GitHub
parent 653ba7e707
commit 363b6f9af8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 85 additions and 37 deletions

View File

@ -46,9 +46,9 @@ jobs:
GOARCH: amd64 GOARCH: amd64
GOPROXY: https://proxy.golang.org GOPROXY: https://proxy.golang.org
JDK_VER: ${{ matrix.java }} 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_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_CLI_REF:
DAPR_REF: DAPR_REF:
TOXIPROXY_URL: https://github.com/Shopify/toxiproxy/releases/download/v2.5.0/toxiproxy-server-linux-amd64 TOXIPROXY_URL: https://github.com/Shopify/toxiproxy/releases/download/v2.5.0/toxiproxy-server-linux-amd64

View File

@ -37,9 +37,9 @@ jobs:
GOARCH: amd64 GOARCH: amd64
GOPROXY: https://proxy.golang.org GOPROXY: https://proxy.golang.org
JDK_VER: ${{ matrix.java }} 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_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_CLI_REF:
DAPR_REF: DAPR_REF:
steps: steps:

View File

@ -134,7 +134,7 @@ public class MethodInvokeIT extends BaseIT {
// TODO(artursouza): change this to INTERNAL once runtime is fixed. // TODO(artursouza): change this to INTERNAL once runtime is fixed.
assertEquals("UNKNOWN", exception.getErrorCode()); assertEquals("UNKNOWN", exception.getErrorCode());
assertNotNull(exception.getMessage()); 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")); assertTrue(new String(exception.getPayload()).contains("Internal Server Error"));
} }
} }

View File

@ -349,7 +349,8 @@ public class DaprHttp implements AutoCloseable {
try { try {
return DAPR_ERROR_DETAILS_OBJECT_MAPPER.readValue(json, DaprError.class); return DAPR_ERROR_DETAILS_OBJECT_MAPPER.readValue(json, DaprError.class);
} catch (IOException e) { } catch (IOException e) {
throw new DaprException("UNKNOWN", new String(json, StandardCharsets.UTF_8), json); // Could not parse DaprError. Return null.
return null;
} }
} }
@ -384,17 +385,13 @@ public class DaprHttp implements AutoCloseable {
try { try {
byte[] payload = getBodyBytesOrEmptyArray(response); byte[] payload = getBodyBytesOrEmptyArray(response);
DaprError error = parseDaprError(payload); DaprError error = parseDaprError(payload);
if ((error != null) && (error.getErrorCode() != null)) { if (error != null) {
if (error.getMessage() != null) { future.completeExceptionally(new DaprException(error, payload, response.code()));
future.completeExceptionally(new DaprException(error, payload));
} else {
future.completeExceptionally(
new DaprException(error.getErrorCode(), "HTTP status code: " + response.code(), payload));
}
return; return;
} }
future.completeExceptionally(new DaprException("UNKNOWN", "HTTP status code: " + response.code(), payload)); future.completeExceptionally(
new DaprException("UNKNOWN", "", payload, response.code()));
return; return;
} catch (DaprException e) { } catch (DaprException e) {
future.completeExceptionally(e); future.completeExceptionally(e);

View File

@ -13,7 +13,9 @@ limitations under the License.
package io.dapr.exceptions; package io.dapr.exceptions;
import com.google.rpc.Status;
import io.grpc.StatusRuntimeException; import io.grpc.StatusRuntimeException;
import io.grpc.protobuf.StatusProto;
import reactor.core.Exceptions; import reactor.core.Exceptions;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -30,26 +32,32 @@ public class DaprException extends RuntimeException {
/** /**
* Dapr's error code for this exception. * Dapr's error code for this exception.
*/ */
private String errorCode; private final String errorCode;
/** /**
* The status details for the error. * The status details for the error.
*/ */
private DaprErrorDetails errorDetails; private final DaprErrorDetails errorDetails;
/** /**
* Optional payload, if the exception came from a response body. * 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. * New exception from a server-side generated error code and message.
* *
* @param daprError Server-side error. * @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) { public DaprException(DaprError daprError, byte[] payload, int httpStatusCode) {
this(daprError.getErrorCode(), daprError.getMessage(), daprError.getDetails(), payload); this(daprError.getErrorCode(), daprError.getMessage(), daprError.getDetails(), payload, httpStatusCode);
} }
/** /**
@ -77,10 +85,11 @@ public class DaprException extends RuntimeException {
* *
* @param errorCode Client-side error code. * @param errorCode Client-side error code.
* @param message Client-side error message. * @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) { public DaprException(String errorCode, String message, byte[] payload, int httpStatusCode) {
this(errorCode, message, DaprErrorDetails.EMPTY_INSTANCE, payload); this(errorCode, message, DaprErrorDetails.EMPTY_INSTANCE, payload, httpStatusCode);
} }
/** /**
@ -89,10 +98,12 @@ public class DaprException extends RuntimeException {
* @param errorCode Client-side error code. * @param errorCode Client-side error code.
* @param message Client-side error message. * @param message Client-side error message.
* @param errorDetails Details of the error from runtime. * @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) { public DaprException(
this(errorCode, message, new DaprErrorDetails(errorDetails), payload); String errorCode, String message, List<Map<String, Object>> errorDetails, byte[] payload, int httpStatusCode) {
this(errorCode, message, new DaprErrorDetails(errorDetails), payload, httpStatusCode);
} }
/** /**
@ -101,10 +112,29 @@ public class DaprException extends RuntimeException {
* @param errorCode Client-side error code. * @param errorCode Client-side error code.
* @param message Client-side error message. * @param message Client-side error message.
* @param errorDetails Details of the error from runtime. * @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) { 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.errorCode = errorCode;
this.errorDetails = errorDetails; this.errorDetails = errorDetails;
this.payload = payload; this.payload = payload;
@ -120,8 +150,11 @@ public class DaprException extends RuntimeException {
* unknown.) * unknown.)
*/ */
public DaprException(String errorCode, String message, Throwable cause) { 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.errorCode = errorCode;
this.errorDetails = DaprErrorDetails.EMPTY_INSTANCE;
this.payload = null;
} }
/** /**
@ -137,7 +170,8 @@ public class DaprException extends RuntimeException {
*/ */
public DaprException( public DaprException(
String errorCode, String message, Throwable cause, DaprErrorDetails errorDetails, byte[] payload) { 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.errorCode = errorCode;
this.errorDetails = errorDetails == null ? DaprErrorDetails.EMPTY_INSTANCE : errorDetails; this.errorDetails = errorDetails == null ? DaprErrorDetails.EMPTY_INSTANCE : errorDetails;
this.payload = payload; this.payload = payload;
@ -170,6 +204,15 @@ public class DaprException extends RuntimeException {
return this.payload == null ? null : this.payload.clone(); 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). * Wraps an exception into DaprException (if not already DaprException).
* *
@ -266,7 +309,7 @@ public class DaprException extends RuntimeException {
while (e != null) { while (e != null) {
if (e instanceof StatusRuntimeException) { if (e instanceof StatusRuntimeException) {
StatusRuntimeException statusRuntimeException = (StatusRuntimeException) e; 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); DaprErrorDetails errorDetails = new DaprErrorDetails(status);
@ -289,11 +332,18 @@ public class DaprException extends RuntimeException {
return new DaprException(exception); return new DaprException(exception);
} }
private static String emptyIfNull(String str) { private static String buildErrorMessage(String errorCode, int httpStatusCode, String message) {
if (str == null) { String result = ((errorCode == null) || errorCode.isEmpty()) ? "UNKNOWN: " : errorCode + ": ";
return ""; 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;
} }
} }

View File

@ -274,7 +274,8 @@ public class DaprClientHttpTest {
}); });
assertEquals("MYCODE", exception.getErrorCode()); 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 @Test
@ -308,7 +309,7 @@ public class DaprClientHttpTest {
}); });
assertEquals("UNKNOWN", exception.getErrorCode()); 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())); assertEquals("{ \"anything\": 7 }", new String(exception.getPayload()));
} }