View Javadoc
1   /*
2    * Copyright 2019 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.bremersee.exception.feign;
18  
19  import feign.FeignException;
20  import feign.Request;
21  import java.util.Collection;
22  import java.util.Collections;
23  import java.util.Map;
24  import javax.validation.constraints.NotNull;
25  import lombok.Getter;
26  import org.bremersee.exception.ErrorCodeAware;
27  import org.bremersee.exception.HttpResponseHeadersAware;
28  import org.bremersee.exception.HttpStatusAware;
29  import org.bremersee.exception.RestApiExceptionAware;
30  import org.bremersee.exception.RestApiExceptionUtils;
31  import org.bremersee.exception.model.RestApiException;
32  import org.springframework.http.HttpStatus;
33  import org.springframework.lang.Nullable;
34  import org.springframework.util.StringUtils;
35  
36  /**
37   * Feign exception that stores the error payload as a {@link RestApiException}. If the error payload cannot be parsed as
38   * {@link RestApiException}, the whole body of the error payload will be stored in the message field of the {@link
39   * RestApiException}.
40   *
41   * @author Christian Bremer
42   */
43  public class FeignClientException extends FeignException implements HttpStatusAware,
44      HttpResponseHeadersAware, RestApiExceptionAware, ErrorCodeAware {
45  
46    @Getter
47    private final Request request;
48  
49    @NotNull
50    private final Map<String, ? extends Collection<String>> headers;
51  
52    @Getter
53    private final RestApiException restApiException;
54  
55    /**
56     * Default constructor.
57     *
58     * @param request the original request
59     * @param headers the response headers
60     * @param status the response status code
61     * @param message the message of this {@link FeignClientException}
62     * @param restApiException the rest api exception
63     */
64    @SuppressWarnings("WeakerAccess")
65    public FeignClientException(
66        @Nullable final Request request,
67        @Nullable final Map<String, ? extends Collection<String>> headers,
68        final int status,
69        @Nullable final String message,
70        @Nullable final RestApiException restApiException) {
71  
72      super(
73          resolveHttpStatusCode(status),
74          StringUtils.hasText(message)
75              ? message
76              : RestApiExceptionUtils.NO_MESSAGE_VALUE,
77          request != null
78              ? request.body()
79              : null);
80      this.request = request;
81      this.headers = headers != null ? headers : Collections.emptyMap();
82      this.restApiException = restApiException;
83    }
84  
85    @Override
86    public Map<String, ? extends Collection<String>> getMultiValueHeaders() {
87      return headers;
88    }
89  
90    @Override
91    public String getErrorCode() {
92      return restApiException != null ? restApiException.getErrorCode() : null;
93    }
94  
95    private static int resolveHttpStatusCode(final int httpStatusCode) {
96      final HttpStatus httpStatus = HttpStatus.resolve(httpStatusCode);
97      return httpStatus != null ? httpStatus.value() : HttpStatus.INTERNAL_SERVER_ERROR.value();
98    }
99  
100 }