Skip to content

Conversation

@feliperaul
Copy link

According to the docs:

The raise_on_request_failure option, when enabled, will raise a Grover::JavaScript::RequestFailedError if the initial content request or any subsequent asset request returns a bad response or times out.

However, as it is, the error will only be raised after the wait_for_selector or wait_for_function are performed.

This means that, for example, if grover hits a 401 (Unauthorized) response when visiting a URL, it will not raise immediately; instead, it will time out because the selector wasn't found.

This pull request extracts the error handling to a separate function, and invokes it after the page navigation, so that if raise_on_request_failure is true, an error will be raised without having to wait for a selector/function that will inevitably never happen.

Copy link
Contributor

@abrom abrom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @feliperaul however I can see that this would negatively impact people expecting the current behaviour. Although I've outlined a solution that should work for both.

Before merging I'd also like to see a spec that validates this behaviour. Take a look at the existing ones in spec/grover/processor_spec.rb. It could try request something that should fail, but also specify 'waitForSelector' => '#never-going-to-exist' or similar, then check that the request fails with the 4xx error and not a timeout. Have a crack at it and let me know if you need help 😄

Comment on lines 22 to 35
function RequestFailedError(errors) {
this.name = "RequestFailedError";
this.message = errors.map(e => {
if (e.failure()) {
return e.failure().errorText + " at " + e.url();
} else if (e.response() && e.response().status()) {
return e.response().status() + " " + e.url();
} else {
return "UnknownError " + e.url()
}
}).join("\n");
}

RequestFailedError.prototype = Error.prototype;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could move this up outside of this function

const _processPage = (async (convertAction, urlOrHtml, options) => {
let browser, errors = [], tmpDir;

const handleErrors = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not so sure about this method name.. handleErrors is a little nondescript. Maybe handleRequestErrors ?

the errors variable probably should have been named in a similar fashion!

await page.goto(displayUrl || 'http://example.com', requestOptions);
}

handleErrors();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that the opposite also needs to hold true. ie if the wait_for_selector/wait_for_function is waiting for some async data loading to complete and you want to have an error alerted if/when those have completed. This would be a breaking change for anyone expecting the current behaviour 😉

It looks like if we checked for errors right away AND after the delayed checks it should resolve your use case whilst still allowing the behaviour to retain it's existing function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants