Skip to content
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

Make ParseError checking more clear #273

Merged

Conversation

alextes
Copy link
Contributor

@alextes alextes commented Feb 14, 2017

JSON test 'should have statusCode in err' requires an instance of
ParseError to compare to but has no opts or data to pass. This commit
makes those arguments optional allowing for empty ParseError
construction.

@floatdrop
Copy link
Contributor

Why not pass those dummy values to ParseError in test?

@alextes
Copy link
Contributor Author

alextes commented Feb 15, 2017

That would be much nicer @floatdrop!
I'd much rather have the test explicitly use less-sensible arguments than making the actual code more lenient by making the less-sensible arguments defaults.

I didn't do this straight off because I didn't know it was possible. Looking at the ava docs for .throws:

error can be an error constructor, error message, regex matched against the error message, or validation function.

Regardless, the following works:

const err = await t.throws(got(`${s.url}/non200-invalid`, {json: true}), 
	got.ParseError(new Error(), 500, {}, ''));

But to my understanding that's passing an instance, not any of the above, and to make things worse, once I comply with the linting rules and use the 'new' keyword things stop working and I get confused.

Started digging around in the node source, and played around with argument binding, but neither have worked out yet and sadly I don't have more time this morning. I'll try and continue this soon!

Thanks for the suggestion @floatdrop.

@sindresorhus
Copy link
Owner

Maybe this would work, or if not, we could always just check the individual properties:

const err = await t.throws(got(`${s.url}/non200-invalid`, {json: true}));
t.deepEqual(err, got.ParseError(new Error(), 500, {}, ''));

@alextes
Copy link
Contributor Author

alextes commented Feb 23, 2017

I figured out why it worked without the new operator. It's because the custom error constructor returns undefined in that case. Which if you're interested fails this check which means node's assert throws nothing, and ava returns the result obtained here which is the HTTPError which also has a property statusCode set to 500.

Now that I understand some of the internals of .throws in NodeJS and AVA that AVA PR we talked about in #267 should quickly follow 😁.

Errors are notoriously inaccessible, you can't iterate them, I tried anyway, but deepEqual is out.

I really like @sindresorhus 's suggestion to just check props then, the way I see it that means we have three okay options. Every error should have a constructor, a message, and a name. That would respectively make the output when some non ParseError was thrown:
Using constructor:
error_constructor
Using message:
error_message
Using name:
error_name

I like constructor best because I know it's a solid way to tell if two instances come from the same object. Visually, using constructor sucks and comparing name seems most clear to me.

Sorry for taking so long to get back to you two. I'd say it's your call!

@alextes alextes changed the title Make ParseError construction more lenient Make ParseError checking more clear Mar 8, 2017
@alextes alextes force-pushed the lenient-error-construction branch from 621c311 to 22b76aa Compare March 8, 2017 11:49
test/json.js Outdated
@@ -74,7 +74,8 @@ test('catches errors on invalid non-200 responses', async t => {
});

test('should have statusCode in err', async t => {
const err = await t.throws(got(`${s.url}/non200-invalid`, {json: true}), got.ParseError);
const err = await t.throws(got(`${s.url}/non200-invalid`, {json: true}));
t.is(err.constructor, new got.ParseError(new Error(), 500, {}, '').constructor);
Copy link
Owner

Choose a reason for hiding this comment

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

Why not just t.is(err.constructor, got.ParseError);?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair question. Too long ago to remember what the issue was. Fairly sure I tried. But maybe I wrongly assumed t.is would run into the same problem as t.throws. I'll try tonight!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You were super right. That works fine. Updated the PR.

Since we're dealing with a custom error constructor `t.throws` has a
hard time checking the instance is the one we expect. This commit
changes checking to use the constructor error property instead.
@alextes alextes force-pushed the lenient-error-construction branch from 22b76aa to 8642449 Compare March 8, 2017 17:17
@sindresorhus sindresorhus merged commit a6907b4 into sindresorhus:master Mar 8, 2017
@sindresorhus
Copy link
Owner

👍

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.

None yet

3 participants