-
-
Notifications
You must be signed in to change notification settings - Fork 390
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
Consider enable nullable annotation #752
Comments
Can you help me understand if using Flurl in a project where nullable reference types are enabled may cause actual problems? Is it just that nullable types have a certain "self-documenting" nature to them? I'll admit I'm not fully up to speed on them, but as far as I know, properly introducing them in big(ish), established codebase may require lots of changes all over the place, so I want to understand if the benefits are worth the effort. |
I'd like to jump in here and share my thoughts. One case I ran up on is this: case FlurlHttpException e2:
_log.Error("HTTP error: {Message}", e2.SanitizedExceptionMessage());
var errors = await e2.GetResponseJsonAsync<IReadOnlyCollection<ValidationErrorHttpResponse>>();
foreach (var error in errors)
{
_log.Error("Reason: {Error}", error.ErrorMessage);
}
break; The documentation wasn't very helpful, but it seems like public async Task<T> GetJsonAsync<T>() {
if (_streamRead) {
if (_capturedBody == null) return default;
if (_capturedBody is T body) return body;
}
var call = ResponseMessage.RequestMessage.GetFlurlCall();
_serializer = _serializer ?? call.Request.Settings.JsonSerializer;
try {
if (_streamRead) {
// Stream was read but captured as a different type than T. If it was captured as a string,
// we should be in good shape. If it was deserialized to a different type, the best we can
// do is serialize it and then deserialize to T, and we could lose data. But that's a very
// uncommon scenario, hopefully. https://github.com/tmenier/Flurl/issues/571#issuecomment-881712479
var s = _capturedBody as string ?? _serializer.Serialize(_capturedBody);
_capturedBody = _serializer.Deserialize<T>(s);
}
else {
using (var stream = await ResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false))
_capturedBody = _serializer.Deserialize<T>(stream);
}
return (T)_capturedBody;
}
catch (Exception ex) {
_serializer = null;
_capturedBody = await ResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
_streamRead = true;
call.Exception = new FlurlParsingException(call, "JSON", ex);
await FlurlRequest.HandleExceptionAsync(call, call.Exception, CancellationToken.None).ConfigureAwait(false);
return default;
}
finally {
_streamRead = true;
}
} The above code showed me that if That means the code from my first snippet is being misled. The Roslyn analyzers assume that the return value may not be null because the return type is |
To add to this, we ran into a NRE in the |
I should pay more attention to my mailbox =) @tmenier What do you think? We could do it partially by using nullable pragma |
I'll add this to the backlog.
I'm not sure I agree. Both examples above demonstrate the same basic problem: getting a null result was surprising. That said, they're good examples of why this would be a good enhancement. |
That's great! |
@Tunduk Also I appreciate your offer to help! That would be great, but I would say don't start quite yet. I'm catching up on a few things and will be making some major commits for 4.0 soon. I think it would be smart to come through with your enhancements after I'm mostly done ripping things up. :) One other thing to consider: Flurl has broad cross-platform support, per best practices, including platforms that do not support nullable reference types. This looks like a useful guide: https://www.meziantou.net/how-to-use-nullable-reference-types-in-dotnet-standard-2-0-and-dotnet-.htm But I'll warn you in advance: I don't know that I want the code to be littered with tons of |
I don't have much experience with them myself, but in the link you shared, it does talk about nullability attributes. I didn't read the full page, but that seems to correlate with other pages like this one. Maybe the attributes can be used without sprinkling |
I also think that you wouldn't need |
Since .NET 6 nullable reference types are enabled by default. It would be good to enable it in Flurl too.
There are a lot of comments like "otherwise null".
Of course, I am ready to help with this issue.
The text was updated successfully, but these errors were encountered: