public static WebsocketRequestException newBadRequest( String errorMessage, GatewayMessage request) { return new WebsocketRequestException( new io.scalecube.services.exceptions.BadRequestException(errorMessage), request); }
@Override public String toString() { return getClass().getSimpleName() + "{errorMessage=" + getMessage() + '}'; } }
@Override public String toString() { return getClass().getSimpleName() + "{errorCode=" + errorCode + ", errorMessage=" + getMessage() + '}'; } }
@Override public Throwable toError(ServiceMessage message) { ErrorData data = message.data(); int errorType = message.errorType(); int errorCode = data.getErrorCode(); String errorMessage = data.getErrorMessage(); switch (errorType) { case BadRequestException.ERROR_TYPE: return new BadRequestException(errorCode, errorMessage); case UnauthorizedException.ERROR_TYPE: return new UnauthorizedException(errorCode, errorMessage); case ServiceUnavailableException.ERROR_TYPE: return new ServiceUnavailableException(errorCode, errorMessage); case InternalServiceException.ERROR_TYPE: return new InternalServiceException(errorCode, errorMessage); // Handle other types of Service Exceptions here default: return new InternalServiceException(errorCode, errorMessage); } }
/** * Performs basic validation on incoming message: qualifier must be present, method invoker must * be present in the method registry by incoming qualifier. May throw exception * * @param message incoming message * @throws ServiceException in case qualfier is missing or method invoker is missing by given * qualifier */ private void validateRequest(ServiceMessage message) throws ServiceException { if (message.qualifier() == null) { Optional.ofNullable(message.data()) .ifPresent(ReferenceCountUtil::safestRelease); // release message data if any LOGGER.error("Failed to invoke service with msg={}: qualifier is null", message); throw new BadRequestException("Qualifier is null in service msg request: " + message); } if (!methodRegistry.containsInvoker(message.qualifier())) { Optional.ofNullable(message.data()) .ifPresent(ReferenceCountUtil::safestRelease); // release message data if any LOGGER.error( "Failed to invoke service with msg={}: no service invoker found by qualifier={}", message, message.qualifier()); throw new ServiceUnavailableException( "No service invoker found by qualifier=" + message.qualifier()); } } }
private ServiceUnavailableException noReachableMemberException(ServiceMessage request) { LOGGER.error( "Failed to invoke service, " + "No reachable member with such service definition [{}], args [{}]", request.qualifier(), request); return new ServiceUnavailableException( "No reachable member with such service: " + request.qualifier()); }
private <T> Mono<T> toConnectionClosedException() { return Mono.error(new ConnectionClosedException("Connection closed")); } }
@Override public ServiceMessage toMessage(Throwable throwable) { // implement service mapping logic if (throwable instanceof ServiceAException) { ServiceAException e = (ServiceAException) throwable; return ServiceMessage.error(BadRequestException.ERROR_TYPE, e.code(), e.getMessage()); } // or delegate it to default mapper return DefaultErrorMapper.INSTANCE.toMessage(throwable); } }
private Flux<ServiceMessage> toMessage(Throwable ex) { return Flux.just(ExceptionProcessor.toMessage(ex)); }
/** * Invokes service method with single response. * * @param message request service message * @param dataDecoder function to create new service message with decoded data * @return mono of service message */ public Mono<ServiceMessage> invokeOne( ServiceMessage message, BiFunction<ServiceMessage, Class<?>, ServiceMessage> dataDecoder) { return Mono.defer(() -> Mono.from(invoke(toRequest(message, dataDecoder)))) .map(this::toResponse) .onErrorResume(throwable -> Mono.just(errorMapper.toMessage(throwable))); }
private ServiceMessage throwIfError(ServiceMessage message) { if (message.isError() && message.hasData(ErrorData.class)) { throw Exceptions.propagate(errorMapper.toError(message)); } return message; }
@Override public String toString() { return getClass().getSimpleName() + "{errorMessage=" + getMessage() + '}'; } }
@Override public Throwable toError(ServiceMessage message) { ErrorData data = message.data(); if (data.getErrorCode() == 42) { // implement service mapping logic return new ServiceAException(data.getErrorMessage()); } else { // or delegate it to default mapper return DefaultErrorMapper.INSTANCE.toError(message); } } }
@Override public Throwable toError(ClientMessage message) { ErrorData errorData = message.data(); int errorType = message.errorType(); int errorCode = errorData.getErrorCode(); String errorMessage = errorData.getErrorMessage(); switch (errorType) { case BadRequestException.ERROR_TYPE: return new BadRequestException(errorCode, errorMessage); case UnauthorizedException.ERROR_TYPE: return new UnauthorizedException(errorCode, errorMessage); case ServiceUnavailableException.ERROR_TYPE: return new ServiceUnavailableException(errorCode, errorMessage); case InternalServiceException.ERROR_TYPE: return new InternalServiceException(errorCode, errorMessage); // Handle other types of Service Exceptions here default: return new InternalServiceException(errorCode, errorMessage); } } }
private ServiceUnavailableException noReachableMemberException(ServiceMessage request) { LOGGER.error( "Failed to invoke service, " + "No reachable member with such service definition [{}], args [{}]", request.qualifier(), request); return new ServiceUnavailableException( "No reachable member with such service: " + request.qualifier()); }
private <T> Mono<T> toConnectionClosedException() { return Mono.error(new ConnectionClosedException("Connection closed")); } }
/** * Invokes service method with bidirectional communication. * * @param publisher request service message * @param dataDecoder function to create new service message with decoded data * @return flux of service messages */ public Flux<ServiceMessage> invokeBidirectional( Publisher<ServiceMessage> publisher, BiFunction<ServiceMessage, Class<?>, ServiceMessage> dataDecoder) { return Flux.from(publisher) .map(message -> toRequest(message, dataDecoder)) .transform(this::invoke) .map(this::toResponse) .onErrorResume(throwable -> Flux.just(errorMapper.toMessage(throwable))); }
private ServiceMessage throwIfError(ServiceMessage message) { if (message.isError() && message.hasData(ErrorData.class)) { throw Exceptions.propagate(errorMapper.toError(message)); } return message; }
private <T> Mono<T> toConnectionClosedException() { return Mono.error(new ConnectionClosedException("Connection closed")); } }
/** * Invokes service method with message stream response. * * @param message request service message * @param dataDecoder function to create new service message with decoded data * @return flux of service messages */ public Flux<ServiceMessage> invokeMany( ServiceMessage message, BiFunction<ServiceMessage, Class<?>, ServiceMessage> dataDecoder) { return Flux.defer(() -> Flux.from(invoke(toRequest(message, dataDecoder)))) .map(this::toResponse) .onErrorResume(throwable -> Flux.just(errorMapper.toMessage(throwable))); }