|
4 | 4 | import com.fasterxml.jackson.databind.JsonNode; |
5 | 5 | import com.fasterxml.jackson.databind.ObjectMapper; |
6 | 6 | import io.facturapi.FacturapiException; |
| 7 | +import io.facturapi.models.ApiError; |
7 | 8 | import java.io.IOException; |
8 | 9 | import java.io.InputStream; |
9 | 10 | import java.net.URI; |
@@ -146,21 +147,7 @@ private InputStream requestStream(String method, String path, Object body) { |
146 | 147 | responseBytes = errorStream == null ? new byte[0] : errorStream.readAllBytes(); |
147 | 148 | } |
148 | 149 | String bodyText = responseBytes.length == 0 ? "" : new String(responseBytes, StandardCharsets.UTF_8); |
149 | | - String message = "Request failed with status " + statusCode; |
150 | | - try { |
151 | | - JsonNode error = objectMapper.readTree(bodyText); |
152 | | - JsonNode messageNode = firstDefined(error, "message", "error", "detail"); |
153 | | - if (messageNode != null && messageNode.isTextual()) { |
154 | | - message = messageNode.asText(); |
155 | | - } else if (!bodyText.isEmpty()) { |
156 | | - message = bodyText; |
157 | | - } |
158 | | - } catch (Exception ignored) { |
159 | | - if (!bodyText.isEmpty()) { |
160 | | - message = bodyText; |
161 | | - } |
162 | | - } |
163 | | - throw new FacturapiException(message, statusCode, bodyText); |
| 150 | + throw new FacturapiException(parseApiError(bodyText, statusCode), bodyText); |
164 | 151 | } |
165 | 152 | return response.body(); |
166 | 153 | } catch (IOException e) { |
@@ -215,6 +202,66 @@ private static JsonNode firstDefined(JsonNode node, String... keys) { |
215 | 202 | return null; |
216 | 203 | } |
217 | 204 |
|
| 205 | + private ApiError parseApiError(String bodyText, int statusCode) { |
| 206 | + ApiError apiError = null; |
| 207 | + if (bodyText != null && !bodyText.isBlank()) { |
| 208 | + try { |
| 209 | + apiError = objectMapper.readValue(bodyText, ApiError.class); |
| 210 | + } catch (Exception ignored) { |
| 211 | + try { |
| 212 | + JsonNode error = objectMapper.readTree(bodyText); |
| 213 | + apiError = new ApiError(); |
| 214 | + |
| 215 | + JsonNode messageNode = firstDefined(error, "message", "error", "detail"); |
| 216 | + if (messageNode != null && messageNode.isTextual()) { |
| 217 | + apiError.setMessage(messageNode.asText()); |
| 218 | + } else { |
| 219 | + apiError.setMessage(bodyText); |
| 220 | + } |
| 221 | + |
| 222 | + JsonNode statusNode = firstDefined(error, "status"); |
| 223 | + if (statusNode != null) { |
| 224 | + apiError.setStatus(statusNode); |
| 225 | + } |
| 226 | + |
| 227 | + JsonNode codeNode = firstDefined(error, "code"); |
| 228 | + if (codeNode != null) { |
| 229 | + apiError.setCode(codeNode); |
| 230 | + } |
| 231 | + |
| 232 | + JsonNode pathNode = firstDefined(error, "path"); |
| 233 | + if (pathNode != null && pathNode.isTextual()) { |
| 234 | + apiError.setPath(pathNode.asText()); |
| 235 | + } |
| 236 | + |
| 237 | + JsonNode okNode = firstDefined(error, "ok"); |
| 238 | + if (okNode != null && okNode.isBoolean()) { |
| 239 | + apiError.setOk(okNode.asBoolean()); |
| 240 | + } |
| 241 | + } catch (Exception secondaryIgnored) { |
| 242 | + apiError = new ApiError(); |
| 243 | + apiError.setMessage(bodyText.isBlank() ? "Request failed with status " + statusCode : bodyText); |
| 244 | + } |
| 245 | + } |
| 246 | + } |
| 247 | + |
| 248 | + if (apiError == null) { |
| 249 | + apiError = new ApiError(); |
| 250 | + apiError.setMessage("Request failed with status " + statusCode); |
| 251 | + } |
| 252 | + |
| 253 | + if (apiError.getMessage() == null || apiError.getMessage().isBlank()) { |
| 254 | + apiError.setMessage("Request failed with status " + statusCode); |
| 255 | + } |
| 256 | + if (apiError.getStatus() == null) { |
| 257 | + apiError.setStatus(statusCode); |
| 258 | + } |
| 259 | + if (!apiError.isOk()) { |
| 260 | + apiError.setOk(false); |
| 261 | + } |
| 262 | + return apiError; |
| 263 | + } |
| 264 | + |
218 | 265 | private HttpRequest buildRequest( |
219 | 266 | String method, |
220 | 267 | String path, |
@@ -248,21 +295,7 @@ private void validateResponse(HttpResponse<byte[]> response) { |
248 | 295 | int statusCode = response.statusCode(); |
249 | 296 | if (statusCode < 200 || statusCode >= 300) { |
250 | 297 | String bodyText = response.body() == null ? "" : new String(response.body(), StandardCharsets.UTF_8); |
251 | | - String message = "Request failed with status " + statusCode; |
252 | | - try { |
253 | | - JsonNode error = objectMapper.readTree(bodyText); |
254 | | - JsonNode messageNode = firstDefined(error, "message", "error", "detail"); |
255 | | - if (messageNode != null && messageNode.isTextual()) { |
256 | | - message = messageNode.asText(); |
257 | | - } else if (!bodyText.isEmpty()) { |
258 | | - message = bodyText; |
259 | | - } |
260 | | - } catch (Exception ignored) { |
261 | | - if (!bodyText.isEmpty()) { |
262 | | - message = bodyText; |
263 | | - } |
264 | | - } |
265 | | - throw new FacturapiException(message, statusCode, bodyText); |
| 298 | + throw new FacturapiException(parseApiError(bodyText, statusCode), bodyText); |
266 | 299 | } |
267 | 300 | } |
268 | 301 |
|
|
0 commit comments