Skip to content

Commit

Permalink
add error handling in controller
Browse files Browse the repository at this point in the history
  • Loading branch information
zklgame committed Nov 29, 2023
1 parent cce58a3 commit ea0c6b7
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 20 deletions.
6 changes: 4 additions & 2 deletions src/main/java/io/xcherry/core/exception/HttpException.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.xcherry.core.exception.status.ProcessNotFoundException;
import io.xcherry.gen.models.ApiErrorResponse;
import io.xcherry.gen.models.EncodedObject;
import io.xcherry.gen.models.ErrorSubType;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
Expand Down Expand Up @@ -37,9 +38,10 @@ public HttpException(final ObjectEncoder objectEncoder, final FeignException.Fei
}
}

// TODO
apiErrorResponse =
new ApiErrorResponse().details("empty or unable to decode to apiErrorResponse: " + decodeErrorMessage);
new ApiErrorResponse()
.errorSubType(ErrorSubType.UNCATEGORIZED_ERROR)
.details("empty or unable to decode to apiErrorResponse: " + decodeErrorMessage);

Check warning on line 44 in src/main/java/io/xcherry/core/exception/HttpException.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/xcherry/core/exception/HttpException.java#L43-L44

Added lines #L43 - L44 were not covered by tests
}

public static HttpException fromFeignException(
Expand Down
53 changes: 50 additions & 3 deletions src/main/java/io/xcherry/core/worker/WorkerService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.xcherry.core.worker;

import static io.xcherry.core.worker.WorkerServiceResponseEntity.HTTP_STATUS_FAILED_DEPENDENCY;

import com.google.common.collect.ImmutableList;
import io.xcherry.core.command.BaseCommand;
import io.xcherry.core.command.CommandResults;
Expand All @@ -22,6 +24,9 @@
import io.xcherry.gen.models.StateDecision;
import io.xcherry.gen.models.StateMovement;
import io.xcherry.gen.models.TimerCommand;
import io.xcherry.gen.models.WorkerErrorResponse;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
Expand All @@ -37,7 +42,32 @@ public class WorkerService {
private final Registry registry;
private final WorkerServiceOptions workerServiceOptions;

public AsyncStateWaitUntilResponse handleAsyncStateWaitUntil(final AsyncStateWaitUntilRequest request) {
public WorkerServiceResponseEntity handleAsyncStateWaitUntil(final AsyncStateWaitUntilRequest request) {
try {
return WorkerServiceResponseEntity.ok(handleAsyncStateWaitUntilInternal(request));
} catch (final Exception e) {
return processWorkerException(e, HTTP_STATUS_FAILED_DEPENDENCY);

Check warning on line 49 in src/main/java/io/xcherry/core/worker/WorkerService.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/xcherry/core/worker/WorkerService.java#L48-L49

Added lines #L48 - L49 were not covered by tests
}
}

public WorkerServiceResponseEntity handleAsyncStateExecute(final AsyncStateExecuteRequest request) {
try {
// TODO: handling 406
return WorkerServiceResponseEntity.ok(handleAsyncStateExecuteInternal(request));
} catch (final Exception e) {
return processWorkerException(e, HTTP_STATUS_FAILED_DEPENDENCY);

Check warning on line 58 in src/main/java/io/xcherry/core/worker/WorkerService.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/xcherry/core/worker/WorkerService.java#L57-L58

Added lines #L57 - L58 were not covered by tests
}
}

public WorkerServiceResponseEntity handleProcessRpc(final ProcessRpcWorkerRequest request) {
try {
return WorkerServiceResponseEntity.ok(handleProcessRpcInternal(request));
} catch (final Exception e) {
return processWorkerException(e, HTTP_STATUS_FAILED_DEPENDENCY);

Check warning on line 66 in src/main/java/io/xcherry/core/worker/WorkerService.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/xcherry/core/worker/WorkerService.java#L65-L66

Added lines #L65 - L66 were not covered by tests
}
}

private AsyncStateWaitUntilResponse handleAsyncStateWaitUntilInternal(final AsyncStateWaitUntilRequest request) {
final AsyncState state = registry.getProcessState(request.getProcessType(), request.getStateId());
final Object input = workerServiceOptions
.getObjectEncoder()
Expand All @@ -56,7 +86,7 @@ public AsyncStateWaitUntilResponse handleAsyncStateWaitUntil(final AsyncStateWai
.publishToLocalQueue(communication.getLocalQueueMessagesToPublish());
}

public AsyncStateExecuteResponse handleAsyncStateExecute(final AsyncStateExecuteRequest request) {
private AsyncStateExecuteResponse handleAsyncStateExecuteInternal(final AsyncStateExecuteRequest request) {
final AsyncState state = registry.getProcessState(request.getProcessType(), request.getStateId());
final Object input = workerServiceOptions
.getObjectEncoder()
Expand Down Expand Up @@ -85,7 +115,7 @@ public AsyncStateExecuteResponse handleAsyncStateExecute(final AsyncStateExecute
// );
}

public ProcessRpcWorkerResponse handleProcessRpc(final ProcessRpcWorkerRequest request) {
private ProcessRpcWorkerResponse handleProcessRpcInternal(final ProcessRpcWorkerRequest request) {
final Process process = registry.getProcess(request.getProcessType());
final Method rpcMethod = registry.getRpcMethod(request.getProcessType(), request.getRpcName());

Expand Down Expand Up @@ -180,4 +210,21 @@ private CommandRequest toApiModel(final io.xcherry.core.command.CommandRequest c

return apiCommandRequest;
}

private WorkerServiceResponseEntity processWorkerException(final Exception e, final int statusCode) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);

Check warning on line 217 in src/main/java/io/xcherry/core/worker/WorkerService.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/xcherry/core/worker/WorkerService.java#L215-L217

Added lines #L215 - L217 were not covered by tests

String stackTrace = sw.toString(); // stack trace as a string

Check warning on line 219 in src/main/java/io/xcherry/core/worker/WorkerService.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/xcherry/core/worker/WorkerService.java#L219

Added line #L219 was not covered by tests
if (stackTrace.length() > 2000) {
stackTrace = stackTrace.substring(0, 2000) + "...(truncated)";

Check warning on line 221 in src/main/java/io/xcherry/core/worker/WorkerService.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/xcherry/core/worker/WorkerService.java#L221

Added line #L221 was not covered by tests
}

final WorkerErrorResponse workerErrorResponse = new WorkerErrorResponse()
.detail(e.getMessage() + "\n stacktrace: \n" + stackTrace)
.errorType(e.getClass().getName());

Check warning on line 226 in src/main/java/io/xcherry/core/worker/WorkerService.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/xcherry/core/worker/WorkerService.java#L224-L226

Added lines #L224 - L226 were not covered by tests

return new WorkerServiceResponseEntity(statusCode, workerErrorResponse);

Check warning on line 228 in src/main/java/io/xcherry/core/worker/WorkerService.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/xcherry/core/worker/WorkerService.java#L228

Added line #L228 was not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.xcherry.core.worker;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class WorkerServiceResponseEntity {

public static final int HTTP_STATUS_FAILED_DEPENDENCY = 424;

private final int statusCode;
private final Object body;

public static final WorkerServiceResponseEntity ok(final Object body) {
return new WorkerServiceResponseEntity(200, body);
}
}
25 changes: 10 additions & 15 deletions src/test/java/integ/spring/WorkerApiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
import static io.xcherry.core.worker.WorkerService.API_PATH_PROCESS_RPC;

import io.xcherry.core.worker.WorkerService;
import io.xcherry.core.worker.WorkerServiceResponseEntity;
import io.xcherry.gen.models.AsyncStateExecuteRequest;
import io.xcherry.gen.models.AsyncStateExecuteResponse;
import io.xcherry.gen.models.AsyncStateWaitUntilRequest;
import io.xcherry.gen.models.AsyncStateWaitUntilResponse;
import io.xcherry.gen.models.ProcessRpcWorkerRequest;
import io.xcherry.gen.models.ProcessRpcWorkerResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -24,23 +22,20 @@ public class WorkerApiController {
private final WorkerService workerService;

@PostMapping(API_PATH_ASYNC_STATE_WAIT_UNTIL)
public ResponseEntity<AsyncStateWaitUntilResponse> handleAsyncStateWaitUntil(
final @RequestBody AsyncStateWaitUntilRequest request
) {
return ResponseEntity.ok(workerService.handleAsyncStateWaitUntil(request));
public ResponseEntity<?> handleAsyncStateWaitUntil(final @RequestBody AsyncStateWaitUntilRequest request) {
final WorkerServiceResponseEntity responseEntity = workerService.handleAsyncStateWaitUntil(request);
return ResponseEntity.status(responseEntity.getStatusCode()).body(responseEntity.getBody());
}

@PostMapping(API_PATH_ASYNC_STATE_EXECUTE)
public ResponseEntity<AsyncStateExecuteResponse> handleAsyncStateExecute(
final @RequestBody AsyncStateExecuteRequest request
) {
return ResponseEntity.ok(workerService.handleAsyncStateExecute(request));
public ResponseEntity<?> handleAsyncStateExecute(final @RequestBody AsyncStateExecuteRequest request) {
final WorkerServiceResponseEntity responseEntity = workerService.handleAsyncStateExecute(request);
return ResponseEntity.status(responseEntity.getStatusCode()).body(responseEntity.getBody());
}

@PostMapping(API_PATH_PROCESS_RPC)
public ResponseEntity<ProcessRpcWorkerResponse> handleProcessRpc(
final @RequestBody ProcessRpcWorkerRequest request
) {
return ResponseEntity.ok(workerService.handleProcessRpc(request));
public ResponseEntity<?> handleProcessRpc(final @RequestBody ProcessRpcWorkerRequest request) {
final WorkerServiceResponseEntity responseEntity = workerService.handleProcessRpc(request);
return ResponseEntity.status(responseEntity.getStatusCode()).body(responseEntity.getBody());
}
}

0 comments on commit ea0c6b7

Please sign in to comment.