001
002package io.vrap.rmf.base.client.error;
003
004import java.time.ZoneOffset;
005import java.time.ZonedDateTime;
006import java.time.format.DateTimeFormatter;
007import java.util.Optional;
008import java.util.concurrent.TimeoutException;
009
010import io.vrap.rmf.base.client.ApiHttpRequest;
011import io.vrap.rmf.base.client.utils.json.JsonUtils;
012
013public class RmfTimeoutException extends BaseException {
014    private final ApiHttpRequest request;
015    private final String dateAsString = DateTimeFormatter.ISO_INSTANT
016            .format(ZonedDateTime.now().withZoneSameInstant(ZoneOffset.UTC));
017
018    public RmfTimeoutException(final TimeoutException cause) {
019        super(cause.getMessage(), cause);
020        request = null;
021    }
022
023    public RmfTimeoutException(final TimeoutException cause, final ApiHttpRequest request) {
024        super(cause.getMessage(), cause);
025        this.request = request;
026    }
027
028    public ApiHttpRequest getRequest() {
029        return request;
030    }
031
032    @Override
033    public final String getMessage() {
034        return Optional.ofNullable(super.getMessage()).map(s -> "detailMessage: " + s + "\n").orElse("") + httpSummary()
035                + Optional.ofNullable(request)
036                        .map(x -> "" + x.getMethod() + " " + x.getUri())
037                        .map(x -> "endpoint: " + x + "\n")
038                        .orElse("")
039                + "Java: " + System.getProperty("java.version") + "\n" + "cwd: " + System.getProperty("user.dir") + "\n"
040                + "request: " + Optional.ofNullable(request).map(Object::toString).orElse("<unknown>") + "\n"
041                + httpRequestLine() + requestBodyFormatted();
042    }
043
044    private String httpSummary() {
045        try {
046            final StringBuilder builder = new StringBuilder();
047            if (this.request != null) {
048                builder.append("summary: ");
049                final String httpMethod = Optional.of(this.request)
050                        .map(r -> r.getMethod().toString())
051                        .orElseGet(() -> this.request.getMethod().toString());
052
053                final String path = Optional.of(this.request)
054                        .map(ApiHttpRequest::getUri)
055                        .orElseGet(this.request::getUri)
056                        .toString();
057
058                builder.append(httpMethod)
059                        .append(" ")
060                        .append(path)
061                        .append(" failed ")
062                        .append(" on ")
063                        .append(dateAsString)
064                        .append("\n");
065            }
066            return builder.toString();
067        }
068        catch (final Exception e) {
069            return "";
070        }
071    }
072
073    private String httpRequestLine() {
074        if (request == null) {
075            return "";
076        }
077        else {
078            return "http request: " + request.toString() + "\n";
079        }
080    }
081
082    private String requestBodyFormatted() {
083        try {
084            final Optional<String> stringBodyOfHttpRequest = stringBodyOfHttpRequest();
085            final Optional<String> stringBodyOfHttpRequestIntentSupplier = Optional.ofNullable(request)
086                    .map(ApiHttpRequest::getSecuredBody);
087            return Optional
088                    .ofNullable(stringBodyOfHttpRequest.orElse(stringBodyOfHttpRequestIntentSupplier.orElse(null)))
089                    .map(JsonUtils::prettyPrint)
090                    .map(s -> "http request formatted body: " + s + "\n")
091                    .orElse("");
092        }
093        catch (final Exception e) {
094            return "";
095        }
096    }
097
098    private Optional<String> stringBodyOfHttpRequest() {
099        return Optional.ofNullable(request).map(ApiHttpRequest::getSecuredBody);
100    }
101}