False positive on S2583 in C# catch clause

Hello here,
I would wan to report something that looks like a false positive S2583 on SonarLint 8.1.0.95039 for VisualStudio Pro 2022 (not connected mode), when a null check has been performed in a try clause then checked again in the catch clause:

using System;
using System.Collections.Generic;
using System.Globalization;

DateTime? Test_S2583(Dictionary<string, string>? dic = null)
{
	try
	{
		return dic?.ContainsKey("c") == true
			? DateTime.ParseExact(dic["c"], "dd/MM/yyyy HH:mm:ss", CultureInfo.CurrentCulture)
			: null;
	}
	catch (Exception)
	{
		Console.WriteLine(dic is null ? "true" : "false"); // <- s2583 because of the dic?.ContainsKey above
		return null;
	}
}

I’ve seen some other subjects on the topic, but haven’t seen this try…catch error flow.

Hello @Daynvheur,

Welcome to the community!

This is a true positive.
dic cannot be null in the catch clause, because all paths that could throw are executed only if dic is not null.

To illustrate more, we can lower your snippet to:

DateTime? Test_S2583(Dictionary<string, string>? dic = null)
{
    try
    {
        return (dic != null && dic.ContainsKey("c")) ? new Nullable<DateTime>(DateTime.ParseExact(dic["c"], "dd/MM/yyyy HH:mm:ss", CultureInfo.CurrentCulture)) : null;
    }
    catch (Exception)
    {
        Console.WriteLine((dic == null) ? "true" : "false");
        return null;
    }
}

In the lowered snippet, it is more clear that dic cannot be null when entering the catch clause.
If you add a statement that can throw before the return, the issue will not raise anymore. This is because, in this scenario, our symbolic execution engine won’t know whether dic is null or not null.

I hope this helps.

Have a nice day!