How to make an error handling for search not found in ASP.NET API?

Asked

Viewed 122 times

-1

The return outside the Try-catch block returns me an empty array, but what should I put there to return some error message in the API request status? Removing Ienumerable and switching to an Actionresult is not an option because I need to return a list of objects that have a certain foreign key.

    [HttpGet("{id}")]
    public IEnumerable<Project> Get(int id)
    {
            try
            {
                return _acess.GetCourse(id);
            }
            catch (DataException ex)
            {
                BadRequest(ex.Message);
            }
            return _acess.GetCourse(id);
        }
            
    }
  • Apparently you are in controller A returning a list of B items that belong to A. Right? What error do you want to return? When A does not exist or when there is no B item in A?

  • Both options, actually. I don’t know why I should replace the second Return.

  • Saw edit the answer soon. But... The 2nd Return? The 2 are not the same?

  • Another detail, what kind of error do you expect? Do you want to return an error message on the body? If so, it is not usual to do this in Apis, as there are http status code to give feedback information. An example where it makes sense to return the error in body is for validations, which is not the case.

  • So in this case it is correct to return the empty array even? I don’t have much knowledge yet about the subject.

  • This gives a long debate, even though it is specified in RFC 2616. I, in particular, usually return 404 in the 1st case (A does not exist) and 2xx with empty list in the 2nd case (when A has no B). In this second case I have seen people defend the return 404.

  • what returns: return _acess.GetCourse(id);? has how to put the code of this method?

Show 2 more comments

1 answer

1


In fact the ActionResult does not work with this your return, but if you stop using an interface, can already be used.

This method of yours could be:

[HttpGet("{id}")]
public ActionResult<List<Project>> Get(int id)
  => _acess.GetCourse(id)?.ToList();

Update to meet the question comments

According to the specifications of RFC 2616, 404 status must be returned when the requested route does not exist.

The server has not found Anything matching the Request-URI. No Indication is Given of whether the condition is Temporary or Permanent. The 410 (Gone) status code SHOULD be used if the server Knows, through some internally configurable Mechanism, that an old Resource is permanently unavailable and has no Forwarding address. This status code is commonly used when the server does not Wish to Reveal Exactly Why the request has been refused, or when no other Response is applicable.

The specification is open to interpretation, but in my view, as well as what else I find, in case I do not find elements that satisfy a search it is preferable to use the status 200 (OK) or 204 (No Content).

Personally, I prefer using status 200 with an empty list ([] no body) because it is easier to handle both the sending of the result (your API) and the handling of the result (what API clients need to do).

Transporting that to your case, the route of this endpoint should be something like /seucontrolador/{id}/filho, indicating that elements will be returned that depend on a "parent" record. 404 is returned when the parent element does not exist, since the route /seucontrolador/{id}/* in fact does not exist. In other cases, one could return 200 or 204 (should be documented) and the api clients should know how to treat the return.

Code example to achieve the above goal:

[HttpGet("/seucontrolador/{id}/filho")]
public ActionResult<List<Project>> GetFilhos(int id)
{
    // verifica se objeto pai existe
    // ex: if (_acess.Get(id) == null)
    // => melhor usar um método específico, uma vez que não é preciso usar o objeto retornado
    if (false)
    {
        return this.NotFound();
    }

    // Sempre retorna uma lista, mesmo que GetCourse(id) seja null
    return _acess.GetCourse(id)?.ToList() ?? new List<Project>();
}

Following the Asp.net core template itself, to provide examples of the different types of returns.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace WebApplication.Controllers
{
    [ApiController]
    [Route("/")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        // Retorna uma lista e status 200 (OK)
        [HttpGet("lista")]
        public ActionResult<List<WeatherForecast>> Get()
        {
            var rng = new Random();

            return Enumerable.Range(1, 5)
                .Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                })
                .ToList();
        }

        // Retorna uma lista vazia e status 200 (OK)
        [HttpGet("listavazia")]
        public ActionResult<List<WeatherForecast>> GetListaVazia()
        {
            return new List<WeatherForecast>();
        }

        // Retorna status 204 (No Content)
        [HttpGet("null")]
        public ActionResult<List<WeatherForecast>> GetNull()
        {
            return null;
        }

        // Retorna status 404 (Not Found)
        [HttpGet("notfound")]
        public ActionResult<List<WeatherForecast>> GetNotFOund()
        {
            return this.NotFound();
        }
    }
}
  • Keeps giving the same return of empty array as in my code.

  • How is your Getcourse? If you want to return a 404, you will have to refactor some things, for example you can throw an exception in the Getcourse method and capture it in your controller.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.