Home > Enterprise >  How can I catch an exception and send it as json message?
How can I catch an exception and send it as json message?

Time:03-29

I wrote a code but for some reason it doesn't work...can you tell me what's wrong? I want the app not to stop when I get an exception, only to send that exception back as a json message.

Startup.cs Configure method:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v2/swagger.json", "My API");
            });
        }
        //this is the question...?
        app.UseExceptionHandler(c => c.Run(async context =>
        {
                var exception = context.Features.Get<IExceptionHandlerPathFeature>().Error;
                var response = new { Msg = exception.Message };
                await context.Response.WriteAsJsonAsync(response);
        }));

        app.UseHttpsRedirection();

        app.UseStaticFiles();

        app.UseRouting();

        app.UseCors(x => x
           .AllowAnyMethod()
           .AllowAnyHeader()
           .SetIsOriginAllowed(origin => true)
           .AllowCredentials());

        app.UseAuthentication();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<EventHub>("/events");
        });
    }

Logic the method where I throw an exception:

public IEnumerable<object> Search(string text)
    {
        if (text.Length >= 3)
        {
            var result = new List<object>
            {
                clubRepository.GetAll().Where(club => club.ClubName.Contains(text)),
                playerRepository.GetAll().Where(player => player.PlayerName.Contains(text)),
                managerRepository.GetAll().Where(manager => manager.ManagerName.Contains(text)),
                stadiumRepository.GetAll().Where(stadium => stadium.StadiumName.Contains(text))
            };

            return result;
        }
        else
        {
            throw new ArgumentException("The text is not long enough!");
        }
    }

So I would like to get this exception message as json!

Now it is happening --> Image1

I want that to happen --> Image2

CodePudding user response:

If you don't want the application to stop, you should handle the argument exception where you called the Search method.

Code Sample

        try
        {
            Search("a");
        }
        catch (Exception ex)
        {
            // Catch message of argument exception by ex.Message property and call your api methods
            Console.WriteLine(ex.Message);
        }

CodePudding user response:

You can extract exception elements as a key value in a dictionary.

And serialize that into JSON.

Inspired by this answer, here is my method to exract key/value from exception:

public static Dictionary<string, string> GetExceptionDetails(Exception exception)
{
    var properties = exception.GetType()
        .GetProperties();
    var fields = properties
        .Select(property => new
        {
            Name = property.Name,
            Value = property.GetValue(exception, null)
        })
        .Select(x => $"{x.Name} = {(x.Value != null ? x.Value.ToString() : string.Empty)}")
        .ToDictionary(k => k, v => v);
    return fields;
}

For my test I have done this:

private static void CallSome()
{
    throw new Exception("xx");
}

in your try/catch you do the following:

try
{
    CallSome();
}
catch (Exception e)
{
    string str = JsonConvert.SerializeObject(GetExceptionDetails(e));
    Console.WriteLine(str);
}

This will return you a JSON payload.

I use dotnet 6 console app. I have also installed the Newtonsoft.Json package. You can also you dotnet JsonSerializer:

var str = JsonSerializer.Serialize(GetExceptionDetails(e));

Note: Just read this also this. An exception can be heavy for performance. But for debugging or a shorter period to monitor a system is fine IMO.

  • Related