Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fail async method without throwing an exception

Suppose I have the following method, and the code that calls it:

public async Task<MyResult> PerformAction(string parameter)
{
   if(parameter == "fail")
      throw new Exception("You wanted me to fail.");
   return await MyResult.Create(parameter);
}

var resultOne = await PerformAction("fail");
var resultTwo = await PerformAction("success");

This would work fine - but it would throw an exception, incurring the performance cost of the exception.

Is there a way to indicate to the caller that a task failed, without throwing an exception?

like image 880
Mike Christiansen Avatar asked Apr 09 '26 21:04

Mike Christiansen


2 Answers

In your case you can do:

public Task<MyResult> PerformAction(string parameter)
{
   if(parameter == "fail")
   {
      return Task.FromException<MyResult>(new Exception("You wanted me to fail."));
   }
   return MyResult.Create(parameter);
}

Not sure how much faster this will be in terms of performance.

like image 118
Guru Stron Avatar answered Apr 12 '26 09:04

Guru Stron


A common solution to avoid exception generation and propagation when possible is to wrap results in outer objects:

public class Response<T> {
   public IEnumerable<string> Errors {get;set;}
   public bool HasErrors => Errors?.Any() ?? false;
   public bool IsSuccess {get;set;}
   public T Data {get;set;}
}

public async Task<Response<MyResult>> PerformAction(string parameter)
{
   if(parameter == "fail")
      return new Reponse<MyResult>() {
          IsSuccess = false,
          Errors = new string[] {"Failed"}
      };
   return new Response<MyResult>(){
             Result = await MyResult.Create(parameter).ConfigureAwait(false),
             IsSuccess = true
           };
}

var resultOne = await PerformAction("fail");
if (resultOne.HasErrors) { ... }
var resultTwo = await PerformAction("success");
if (resultTwo.HasErrors) { ... }
like image 30
ddfra Avatar answered Apr 12 '26 11:04

ddfra