-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
jslt-152: parse-url error handling control #153
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1265,16 +1265,18 @@ else if (ComparisonOperator.compare(arguments[0], arguments[1], null) > 0) | |
// ===== PARSE-URL | ||
|
||
public static class ParseUrl extends AbstractFunction { | ||
public ParseUrl() { super("parse-url", 1,1);} | ||
public ParseUrl() { super("parse-url", 1, 2); } | ||
|
||
public JsonNode call(JsonNode input, JsonNode[] arguments) { | ||
if (arguments[0].isNull()) | ||
if (arguments.length < 1 || arguments[0].isNull()) | ||
return NullNode.instance; | ||
|
||
String urlString = arguments[0].asText(); | ||
boolean throwOnFailure = arguments.length < 2 || arguments[1].asBoolean(); | ||
|
||
try { | ||
URL aURL = new URL(arguments[0].asText()); | ||
|
||
URL aURL = new URL(urlString); | ||
final ObjectNode objectNode = NodeUtils.mapper.createObjectNode(); | ||
if (aURL.getHost() != null && !aURL.getHost().isEmpty()) | ||
objectNode.put("host", aURL.getHost()); | ||
|
@@ -1303,8 +1305,17 @@ public JsonNode call(JsonNode input, JsonNode[] arguments) { | |
if(aURL.getUserInfo() != null && !aURL.getUserInfo().isEmpty()) | ||
objectNode.put("userinfo", aURL.getUserInfo()); | ||
return objectNode; | ||
} catch (MalformedURLException | UnsupportedEncodingException e) { | ||
throw new JsltException("Can't parse " + urlString, e); | ||
} catch (Throwable e) { | ||
if (throwOnFailure) { | ||
throw new JsltException("Can't parse " + urlString, e); | ||
} else { | ||
final ObjectNode errorNode = NodeUtils.mapper.createObjectNode(); | ||
Class errorClass = e.getClass(); | ||
errorNode.put("error", errorClass.getSimpleName()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not the full class name? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't feel strongly over this. I can change to full class name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to use |
||
errorNode.put("message", e.getMessage()); | ||
errorNode.put("input", urlString); | ||
return errorNode; | ||
} | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -460,3 +460,36 @@ tests: | |
"port": 8443, | ||
"scheme": "https" | ||
} | ||
|
||
# parse-url tests with throwOnFailure set to true should behave as above | ||
|
||
- input: | ||
query: parse-url("https://example.com:8443", true) | ||
output: | | ||
{ | ||
"host": "example.com", | ||
"port": 8443, | ||
"scheme": "https" | ||
} | ||
|
||
# parse-url tests with throwOnFailure set to false should behave as above for good cases | ||
|
||
- input: | ||
query: parse-url("https://example.com:8443", false) | ||
output: | | ||
{ | ||
"host": "example.com", | ||
"port": 8443, | ||
"scheme": "https" | ||
} | ||
|
||
# parse-url tests with throwOnFailure set to false should return an error object for bad cases | ||
|
||
- input: | ||
query: parse-url("this-is-an-invalid-url", false) | ||
output: | | ||
{ | ||
"error": "MalformedURLException", | ||
"message": "no protocol: this-is-an-invalid-url", | ||
"input": "this-is-an-invalid-url" | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need a test of what happens if the second argument is not a boolean. IMHO that should be considered an error: ie, throw an exception. We also need a test of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am unsure how you typically tests for failures. Do you have an example? I looked in the query-tests.yaml and found no obvious cases to me There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added tests |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -826,10 +826,13 @@ format-time(null, "yyyy-MM-dd") => null | |
|
||
## Miscellaneous functions | ||
|
||
### _parse-url(url) -> object_ | ||
### _parse-url(url, throwOnFailure?) -> object_ | ||
|
||
Parses `url` and returns an object with keys [`scheme`, `userinfo`, `host`, `port` `path`, `query`, `parameters`, `fragment` ] | ||
|
||
If the optional `throwOnFailure` argument is not specified invalid URLs will generate an exception. If `throwOnFailure` is set to `false` the `parse-url` returns | ||
an object indicating an error occurred. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to document the shape of that object, and have an example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added some examples below but I agree we could add more documentation on the shape both when good and bad input There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated with more detaild examples. |
||
``` | ||
parse-url("http://example.com").scheme => "http" | ||
parse-url("http://example.com").host => "example.com" | ||
|
@@ -841,4 +844,8 @@ parse-url("https://www.example.com/?aa=1&aa=2&bb=&cc").parameters.bb => [null] | |
parse-url("https://www.example.com/?aa=1&aa=2&bb=&cc").parameters.cc => [null] | ||
parse-url("ftp://username:[email protected]/").userinfo => "username:password" | ||
parse-url("https://example.com:8443").port => 8443 | ||
|
||
parse-url("this-is-an-invalid-url", false).error => "MalformedURLException" | ||
parse-url("this-is-an-invalid-url", false).message => "no protocol: this-is-an-invalid-url" | ||
parse-url("this-is-an-invalid-url", false).input => "this-is-an-invalid-url" | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible regression as this catch is different. However, we ran into
InvalidArgumentException
when having trailing%
which with the current code pattern gave no hints on the problem string.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwable
is perhaps overdoing it, since it's going to catchOutOfMemoryError
and similar things. Perhaps justException
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwable
->Exception
makes sense 👍 We just rushed the fix out without considering that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or we can simulate
NonFatal
:)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now is
Exception