简体   繁体   中英

How to throw exception from an akka actor?

I have a spring boot application which I'm trying to integrate with akka. For most of the endpoints I'm relying on spring boot built in RuntimeException mechanism but akka actors does not allow to throw exception any thoughts?

i have this helper for calling other services :

public ResponseEntity<R> callService(String address
        , MultiValueMap<String, String> headers
        , B body
        , HttpMethod httpMethod
        , ParameterizedTypeReference<R> parameterizedTypeReference
        , ExceptionHandlerCustom exceptionHandlerCustom) {
    try {
        HttpEntity<B> request = new HttpEntity<>(body, headers);
        return restTemplate.exchange(address
                , httpMethod
                , request
                , parameterizedTypeReference);
    } catch (Exception e) {
        if (e instanceof HttpStatusCodeException) {
            HttpStatusCodeException exception = (HttpStatusCodeException) e;
            Gson gson = new Gson();
            Response<String> errorResponse =
                    gson.fromJson(exception.getResponseBodyAsString(), new TypeToken<Response<String>>(){}.getType());
            if (exception.getStatusCode().equals(HttpStatus.BAD_REQUEST)) {
                throw new BadRequestException(errorResponse.getMessage());
            } else if (exception.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) {
                throw new UnauthorizedException("not authorized");
            } else if (exception.getStatusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
                e.printStackTrace();
                throw new InternalServerErrorException();
            } else if (exceptionHandlerCustom != null) {
                exceptionHandlerCustom.handle(e);
            }else
                e.printStackTrace();
        }
        throw e;
    }
}

I have an actor that calls this method and I want to re-throw the exception right when it happens (I know that the life-cycle of an actor cannot be broken)

my exceptions are all like this:

@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {
    public NotFoundException(String message) {
        super(message);
    }
}

and in my actor I have this method:

@Override
    public Receive createReceive() {
    return receiveBuilder()
            .match(CheckUserIdAndProvidedToken.class, message -> {
                getSender().tell(tokenCheckService.checkUserIdAndProvidedToken(message.getToken()
                        , message.getId()), getSelf());
            })
            .build();
}

and in the service I call it like this:

Future<Object> futureOfCheck = ask(checker, new         
TokenCheckActor.CheckUserIdAndProvidedToken(id, token), timeout);

and when exception occurs I like to throw this to clients (spring boot exception in json format):

{
    "timestamp": "2019-02-06T06:42:26.740+0000",
    "status": 404,
    "error": "Not Found",
    "message": "user not found",
    "path": "/xxxx/yyy/ssss"
}

It is possible to pass Exceptions via ask pattern. This is described at ask-send-and-receive-future section of akka docs.

In summary, catch exception within receive method, wrap it with Failure and send it to sender.

try {
  String result = operation();
  getSender().tell(result, getSelf());
} catch (Exception e) {
  getSender().tell(new akka.actor.Status.Failure(e), getSelf());
  throw e;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM