nullは情報を捨ててしまうから可読性が低くなる
エラー許容型を作ってそれを使うのが定石

Errorable<string> s = func();

if(s.HasNoError) WriteLine(s.Value);
else WriteLine(s.ErrorMessage);

if(s.NotFound) ...
if(s.AuthError) ...
if(s.FormatError) ...
...