|
8 | 8 | package io.xh.hoist.http |
9 | 9 |
|
10 | 10 | import groovy.transform.CompileStatic |
11 | | -import groovy.util.logging.Slf4j |
12 | 11 | import io.xh.hoist.exception.ExternalHttpException |
13 | 12 | import io.xh.hoist.json.JSONParser |
| 13 | +import io.xh.hoist.util.StringUtils |
14 | 14 | import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse |
15 | 15 | import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase |
16 | 16 | import org.apache.hc.client5.http.impl.classic.CloseableHttpClient |
@@ -146,32 +146,44 @@ class JSONClient { |
146 | 146 | } |
147 | 147 |
|
148 | 148 | // Attempt to parse a reasonable exception from failed response, but never actually throw if not possible. |
149 | | - private Throwable parseException(CloseableHttpResponse response){ |
| 149 | + private Throwable parseException(CloseableHttpResponse response) { |
150 | 150 | try { |
151 | | - def ex = JSONParser.parseObject(response.entity.content), |
152 | | - className = ex?.className, |
153 | | - msg = ex?.message |
| 151 | + String content = response.entity.content.getText().trim() |
| 152 | + if (!content) return null |
154 | 153 |
|
155 | | - // Message is required |
156 | | - if (msg instanceof String) { |
| 154 | + // [1] We have a valid json object (preferred) |
| 155 | + Map obj = safeParseObject(content) |
| 156 | + if (obj) { |
| 157 | + String msg = obj.message instanceof String ? obj.message : 'Unknown Error' |
157 | 158 |
|
158 | 159 | // Try to rehydrate exception of certain known and present classes |
| 160 | + def className = obj.className |
159 | 161 | if (className instanceof String && |
160 | | - (className.contains('io.xh.hoist') || className.contains('java.lang'))) { |
| 162 | + (className.contains('io.xh.hoist') || className.contains('java.lang'))) { |
161 | 163 | def cls = this.class.classLoader.loadClass(className), |
162 | 164 | constructor = cls?.getConstructor(String) |
163 | | - |
164 | 165 | if (constructor) { |
165 | 166 | return (Throwable) constructor.newInstance(msg) |
166 | 167 | } |
167 | | - |
168 | 168 | } |
169 | | - // otherwise fall back to a runtime exception... |
| 169 | + // otherwise use a runtime exception. |
170 | 170 | return new RuntimeException(msg) |
171 | 171 | } |
172 | | - } catch (Exception ignored) {} |
173 | 172 |
|
174 | | - return null |
| 173 | + // [2] Or just interpret content as a raw string message |
| 174 | + return new RuntimeException(StringUtils.elide(content, 255)) |
| 175 | + } catch (Exception ignored) { |
| 176 | + // [3] ..but in the worst case, just return null |
| 177 | + return null |
| 178 | + } |
| 179 | + } |
| 180 | + |
| 181 | + private Map safeParseObject(String s) { |
| 182 | + try { |
| 183 | + return JSONParser.parseObject(s) |
| 184 | + } catch (Exception ignored) { |
| 185 | + return null |
| 186 | + } |
175 | 187 | } |
176 | 188 |
|
177 | 189 | } |
0 commit comments