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

Exceptions don't display default exception messages when ApiError.Message is empty #1529

Closed
SeanKilleen opened this issue Jan 9, 2017 · 3 comments · Fixed by #1540
Closed

Comments

@SeanKilleen
Copy link
Contributor

SeanKilleen commented Jan 9, 2017

Currently, many exceptions take ApiErrorMessageSafe and display the default text if it's null.

However, this should probably also apply if ApiErrorMessageSafe is empty so that the user gets something.

I came across this while attempting to write out tests for #1528. I didn't want to change too many things in that PR, so figured I'd create this as an off-shoot.

A failing test

Removed this from my previous PR. Expected the default error message (e.g. generic "Request Forbidden") -- actual was an empty string. This was part of ConnectionTests.cs in #1528 before I ripped it out:

[Fact]
public async Task ThrowsAbuseExceptionWithDefaultMessageForUnsafeAbuseResponse()
{
	string messageText = string.Empty;

	var httpClient = Substitute.For<IHttpClient>();
	IResponse response = new Response(
		HttpStatusCode.Forbidden,
		 "{\"message\":\"" + messageText + "\"," +
		"\"documentation_url\":\"https://developer.github.com/v3/#abuse-rate-limits\"}",
	   new Dictionary<string, string>(),
		"application/json");
	httpClient.Send(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
	var connection = new Connection(new ProductHeaderValue("OctokitTests"),
		_exampleUri,
		Substitute.For<ICredentialStore>(),
		httpClient,
		Substitute.For<IJsonSerializer>());

	var exception = await Assert.ThrowsAsync<AbuseException>(
		() => connection.GetResponse<string>(new Uri("endpoint", UriKind.Relative)));

	Assert.Equal("Request Forbidden - Abuse Detection", exception.Message);
}

Potential Fixes

  • The fix for this would likely be updating the Message property of the affected exceptions to do an IsNullOrWhitespace check on ApiErrorMessageSafe.
  • Or, ApiErrorMessageSafe could be changed to return null if the Message string is empty or whitepsace, rather than just returning the message property itself.
@ryangribble
Copy link
Contributor

Is this related to something I found when working on a PR here: #1415 ?

If you see the 2nd bullet point where I talk about the attempted ApiError deserialization never returning a null and thus never falling back to the text payload...

SeanKilleen added a commit to SeanKilleen/octokit.net that referenced this issue Jan 9, 2017
ryangribble pushed a commit that referenced this issue Jan 11, 2017
* Add some tests to be completed

* Actually fail the tests

* Create AbuseException class

Copied from ForbiddenException and then gone over to inherit from it.

* Actually add AbuseException to csproj

* Update test file

* Ran .\build FixProjects

* Test updates

* Default message update for AbuseException

* Separate the exception creation logic

* Remove message assertion -- doesn't matter here

* Additional test for abuse message

* Remove unnecessary variable assignment

* Failing test for unsafe request

* Attempt to fix test

Still broken -- I don't think empty strings count to trigger the default
message

* Remove test that will always fail due to another issue

Opened #1529 to explore this.

* New tests (some failing)

* Passing tests are, like, better than failing tests.

* Last passing test

* Cleanup

* Add test for zero value and fix code

Lol boundary cases.

* cleanup

* Mark ParseRetryAfterSeconds as static

* Add GetObjectData override to AbuseException

To include data for RetryAfterSeconds variable, and satisfy the build
check.

* Add back failing test & skip it

* Change to nullable int with null default

* Fix tests around nullable default

* whitespace fixes

* Compact the logic; tests still pass

* Invert the if statements for compactness / clarity

* Test subclasses & reformatting

* Test name changes

* Whitespace fix

* Remove redundant line
@ryangribble
Copy link
Contributor

Just refreshing my memory with this stuff and yes I agree with your suggestion.

Specifically I think the 2nd suggested fix would be the way to go, since we can "fix" it in one place, rather than needing to fix it in every place that currently has ApiErrorMessageSafe ?? "default error text"

And this is a different situation to what I commented about above - in that case I found that a compeltely invalid json structure in the error message was still returning a default/empty ApiError object because the deserializer creates an object then tries to populate any fields that match the setter properties. This led to code that was never really getting what it expected, since ApiError itself could never be null. Your case is slightly different since it would also happen if there was valid json error payload but the message field was empty string or not present.

@SeanKilleen
Copy link
Contributor Author

👍 Got it, makes sense. I'll put together a PR to un-skip this test and fix it via the decision here.

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 a pull request may close this issue.

2 participants