Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Awaiting with null coalescing operator thrown exception

I'm encountering some strange behavior.

When running this piece of code:

var foo = await actionContext.RequestContext?.Principal?.ToUserTokenAsync() ?? UserToken.UnidentifiedUser;

Principal is null at runtime and I get a null reference exception.

Why it's not just returning --> UserToken.UnidentifiedUser?

like image 236
user10776203 Avatar asked Jun 03 '19 12:06

user10776203


People also ask

Which is null coalescing operator?

The nullish coalescing operator ( ?? ) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined , and otherwise returns its left-hand side operand.

Why we use null coalescing operator?

The null-coalescing operator ?? returns the value of its left-hand operand if it isn't null ; otherwise, it evaluates the right-hand operand and returns its result.

Can you await null?

The addition of async/await to the C# language specification made it easier to write asynchronous code. However while writing code, you'll end up in some cases where you don't have a Task to return in a certain path of your logic or you have a virtual empty method.

Does node support Nullish coalescing operator?

The node version you are using doesn't support the nullish coalescing assignment operator.


1 Answers

I believe this is a precedence problem. Your code is effectively:

var foo = (await actionContext.RequestContext?.Principal?.ToUserTokenAsync()) ??
          UserToken.UnidentifiedUser;

In other words, if the result of awaiting is null, then return UserToken.UnidentifiedUser. But you still try to do the awaiting - which means you might await something that's null, which fails.

What I suspect you want is:

var task = actionContext.RequestContext?.Principal?.ToUserTokenAsync()
    ?? Task.FromResult(UserToken.UnidentifiedUser);
var foo = await task;

Or avoid awaiting entirely when there's a null:

var task = actionContext.RequestContext?.Principal?.ToUserTokenAsync();
var foo = task != null ? await task : UserToken.UnidentifiedUser;
like image 191
Jon Skeet Avatar answered Sep 22 '22 06:09

Jon Skeet