Skip to content

Commit 6b67d05

Browse files
committed
Improved Validate error messages
Filter the Validate class out of ValidationExceptions, to make it simpler to identify where the validation error originated. Made malformed URL and empty selection error messages more explicit. Simplified raising errors for null and empty parameters.
1 parent 653da57 commit 6b67d05

File tree

11 files changed

+218
-64
lines changed

11 files changed

+218
-64
lines changed

CHANGES

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ Release 1.15.3 [PENDING]
44
* Improvement: the Cleaner will preserve the source position of cleaned elements, if source tracking is enabled in the
55
original parse.
66

7+
* Improvement: the error messages output from Validate are more descriptive. Exceptions are now ValidationExceptions
8+
(extending IllegalArgumentException). Stack traces do not include the Validate class, to make it simpler to see
9+
where the exception originated. Common validation errors including malformed URLs and empty selector results have
10+
more explicit error messages.
11+
712
* Bugfix: the DataUtil would incorrectly read from InputStreams that emitted reads less than the requested size. This
813
lead to incorrect results when parsing from chunked server responses, for e.g.
914
<https://github.com/jhy/jsoup/issues/1807>

src/main/java/org/jsoup/helper/HttpConnection.java

+32-32
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,11 @@ public Connection url(URL url) {
179179
}
180180

181181
public Connection url(String url) {
182-
Validate.notEmpty(url, "Must supply a valid URL");
182+
Validate.notEmptyParam(url, "url");
183183
try {
184184
req.url(new URL(encodeUrl(url)));
185185
} catch (MalformedURLException e) {
186-
throw new IllegalArgumentException("Malformed URL: " + url, e);
186+
throw new IllegalArgumentException(String.format("The supplied URL, '%s', is malformed. Make sure it is an absolute URL, and starts with 'http://' or 'https://'.", url), e);
187187
}
188188
return this;
189189
}
@@ -199,7 +199,7 @@ public Connection proxy(String host, int port) {
199199
}
200200

201201
public Connection userAgent(String userAgent) {
202-
Validate.notNull(userAgent, "User agent must not be null");
202+
Validate.notNullParam(userAgent, "userAgent");
203203
req.header(USER_AGENT, userAgent);
204204
return this;
205205
}
@@ -220,7 +220,7 @@ public Connection followRedirects(boolean followRedirects) {
220220
}
221221

222222
public Connection referrer(String referrer) {
223-
Validate.notNull(referrer, "Referrer must not be null");
223+
Validate.notNullParam(referrer, "referrer");
224224
req.header("Referer", referrer);
225225
return this;
226226
}
@@ -263,15 +263,15 @@ public Connection data(String key, String filename, InputStream inputStream, Str
263263
}
264264

265265
public Connection data(Map<String, String> data) {
266-
Validate.notNull(data, "Data map must not be null");
266+
Validate.notNullParam(data, "data");
267267
for (Map.Entry<String, String> entry : data.entrySet()) {
268268
req.data(KeyVal.create(entry.getKey(), entry.getValue()));
269269
}
270270
return this;
271271
}
272272

273273
public Connection data(String... keyvals) {
274-
Validate.notNull(keyvals, "Data key value pairs must not be null");
274+
Validate.notNullParam(keyvals, "keyvals");
275275
Validate.isTrue(keyvals.length %2 == 0, "Must supply an even number of key value pairs");
276276
for (int i = 0; i < keyvals.length; i += 2) {
277277
String key = keyvals[i];
@@ -284,15 +284,15 @@ public Connection data(String... keyvals) {
284284
}
285285

286286
public Connection data(Collection<Connection.KeyVal> data) {
287-
Validate.notNull(data, "Data collection must not be null");
287+
Validate.notNullParam(data, "data");
288288
for (Connection.KeyVal entry: data) {
289289
req.data(entry);
290290
}
291291
return this;
292292
}
293293

294294
public Connection.KeyVal data(String key) {
295-
Validate.notEmpty(key, "Data key must not be empty");
295+
Validate.notEmptyParam(key, "key");
296296
for (Connection.KeyVal keyVal : request().data()) {
297297
if (keyVal.key().equals(key))
298298
return keyVal;
@@ -311,7 +311,7 @@ public Connection header(String name, String value) {
311311
}
312312

313313
public Connection headers(Map<String,String> headers) {
314-
Validate.notNull(headers, "Header map must not be null");
314+
Validate.notNullParam(headers, "headers");
315315
for (Map.Entry<String,String> entry : headers.entrySet()) {
316316
req.header(entry.getKey(),entry.getValue());
317317
}
@@ -324,7 +324,7 @@ public Connection cookie(String name, String value) {
324324
}
325325

326326
public Connection cookies(Map<String, String> cookies) {
327-
Validate.notNull(cookies, "Cookie map must not be null");
327+
Validate.notNullParam(cookies, "cookies");
328328
for (Map.Entry<String, String> entry : cookies.entrySet()) {
329329
req.cookie(entry.getKey(), entry.getValue());
330330
}
@@ -432,7 +432,7 @@ public URL url() {
432432
}
433433

434434
public T url(URL url) {
435-
Validate.notNull(url, "URL must not be null");
435+
Validate.notNullParam(url, "url");
436436
this.url = punyUrl(url); // if calling url(url) directly, does not go through encodeUrl, so we punycode it explicitly. todo - should we encode here as well?
437437
return (T) this;
438438
}
@@ -442,13 +442,13 @@ public Method method() {
442442
}
443443

444444
public T method(Method method) {
445-
Validate.notNull(method, "Method must not be null");
445+
Validate.notNullParam(method, "method");
446446
this.method = method;
447447
return (T) this;
448448
}
449449

450450
public String header(String name) {
451-
Validate.notNull(name, "Header name must not be null");
451+
Validate.notNullParam(name, "name");
452452
List<String> vals = getHeadersCaseInsensitive(name);
453453
if (vals.size() > 0) {
454454
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
@@ -460,7 +460,7 @@ public String header(String name) {
460460

461461
@Override
462462
public T addHeader(String name, String value) {
463-
Validate.notEmpty(name);
463+
Validate.notEmptyParam(name, "name");
464464
//noinspection ConstantConditions
465465
value = value == null ? "" : value;
466466

@@ -476,7 +476,7 @@ public T addHeader(String name, String value) {
476476

477477
@Override
478478
public List<String> headers(String name) {
479-
Validate.notEmpty(name);
479+
Validate.notEmptyParam(name, "name");
480480
return getHeadersCaseInsensitive(name);
481481
}
482482

@@ -530,14 +530,14 @@ private static boolean looksLikeUtf8(byte[] input) {
530530
}
531531

532532
public T header(String name, String value) {
533-
Validate.notEmpty(name, "Header name must not be empty");
533+
Validate.notEmptyParam(name, "name");
534534
removeHeader(name); // ensures we don't get an "accept-encoding" and a "Accept-Encoding"
535535
addHeader(name, value);
536536
return (T) this;
537537
}
538538

539539
public boolean hasHeader(String name) {
540-
Validate.notEmpty(name, "Header name must not be empty");
540+
Validate.notEmptyParam(name, "name");
541541
return !getHeadersCaseInsensitive(name).isEmpty();
542542
}
543543

@@ -556,8 +556,8 @@ public boolean hasHeaderWithValue(String name, String value) {
556556
}
557557

558558
public T removeHeader(String name) {
559-
Validate.notEmpty(name, "Header name must not be empty");
560-
Map.Entry<String, List<String>> entry = scanHeaders(name); // remove is case insensitive too
559+
Validate.notEmptyParam(name, "name");
560+
Map.Entry<String, List<String>> entry = scanHeaders(name); // remove is case-insensitive too
561561
if (entry != null)
562562
headers.remove(entry.getKey()); // ensures correct case
563563
return (T) this;
@@ -600,24 +600,24 @@ private List<String> getHeadersCaseInsensitive(String name) {
600600
}
601601

602602
public String cookie(String name) {
603-
Validate.notEmpty(name, "Cookie name must not be empty");
603+
Validate.notEmptyParam(name, "name");
604604
return cookies.get(name);
605605
}
606606

607607
public T cookie(String name, String value) {
608-
Validate.notEmpty(name, "Cookie name must not be empty");
609-
Validate.notNull(value, "Cookie value must not be null");
608+
Validate.notEmptyParam(name, "name");
609+
Validate.notNullParam(value, "value");
610610
cookies.put(name, value);
611611
return (T) this;
612612
}
613613

614614
public boolean hasCookie(String name) {
615-
Validate.notEmpty(name, "Cookie name must not be empty");
615+
Validate.notEmptyParam(name, "name");
616616
return cookies.containsKey(name);
617617
}
618618

619619
public T removeCookie(String name) {
620-
Validate.notEmpty(name, "Cookie name must not be empty");
620+
Validate.notEmptyParam(name, "name");
621621
cookies.remove(name);
622622
return (T) this;
623623
}
@@ -749,7 +749,7 @@ public Connection.Request ignoreContentType(boolean ignoreContentType) {
749749
}
750750

751751
public Request data(Connection.KeyVal keyval) {
752-
Validate.notNull(keyval, "Key val must not be null");
752+
Validate.notNullParam(keyval, "keyval");
753753
data.add(keyval);
754754
return this;
755755
}
@@ -778,7 +778,7 @@ public Parser parser() {
778778
}
779779

780780
public Connection.Request postDataCharset(String charset) {
781-
Validate.notNull(charset, "Charset must not be null");
781+
Validate.notNullParam(charset, "charset");
782782
if (!Charset.isSupported(charset)) throw new IllegalCharsetNameException(charset);
783783
this.postDataCharset = charset;
784784
return this;
@@ -834,7 +834,7 @@ static Response execute(HttpConnection.Request req, @Nullable Response previousR
834834
Validate.isFalse(req.executing, "Multiple threads were detected trying to execute the same request concurrently. Make sure to use Connection#newRequest() and do not share an executing request between threads.");
835835
req.executing = true;
836836
}
837-
Validate.notNull(req, "Request must not be null");
837+
Validate.notNullParam(req, "req");
838838
URL url = req.url();
839839
Validate.notNull(url, "URL must be specified to connect");
840840
String protocol = url.getProtocol();
@@ -1275,14 +1275,14 @@ public static KeyVal create(String key, String filename, InputStream stream) {
12751275
}
12761276

12771277
private KeyVal(String key, String value) {
1278-
Validate.notEmpty(key, "Data key must not be empty");
1279-
Validate.notNull(value, "Data value must not be null");
1278+
Validate.notEmptyParam(key, "key");
1279+
Validate.notNullParam(value, "value");
12801280
this.key = key;
12811281
this.value = value;
12821282
}
12831283

12841284
public KeyVal key(String key) {
1285-
Validate.notEmpty(key, "Data key must not be empty");
1285+
Validate.notEmptyParam(key, "key");
12861286
this.key = key;
12871287
return this;
12881288
}
@@ -1292,7 +1292,7 @@ public String key() {
12921292
}
12931293

12941294
public KeyVal value(String value) {
1295-
Validate.notNull(value, "Data value must not be null");
1295+
Validate.notNullParam(value, "value");
12961296
this.value = value;
12971297
return this;
12981298
}
@@ -1302,7 +1302,7 @@ public String value() {
13021302
}
13031303

13041304
public KeyVal inputStream(InputStream inputStream) {
1305-
Validate.notNull(value, "Data input stream must not be null");
1305+
Validate.notNullParam(value, "inputStream");
13061306
this.stream = inputStream;
13071307
return this;
13081308
}

0 commit comments

Comments
 (0)