views:

54

answers:

3

Best practice to throw the exception if no entry found in the db?

// CONTROLLER
public ActionResult Edit(int categoryId, int id)
{
    Product target = Products.GetById(id);
    if (target == null) throw new HttpException(404, "Product not found");

    return View("Edit", target);
}

// REPOSITORY
public Product GetById(int id)
{
    return context.Products.FirstOrDefault(x => x.productId == id);
}

or

// CONTROLLER
public ActionResult Edit(int categoryId, int id)
{
    return View("Edit", Products.GetById(id));
}

// REPOSITORY
public Product GetById(int id)
{
    Product target = context.Products.FirstOrDefault(x => x.productId == id);
    if (target == null) throw new HttpException(404, "Product not found with given id");

    return target;
}
A: 

I would throw httpexceptions in the contraoller, and return null from the repository.

Nate Bross
Return null from the repository.. that dosent make sense - could you go a bit more in depth please?
ebb
I meant `...OrDefault();` ...
Nate Bross
A: 

Do not throw a HttpException in the Repository, as you may want to reuse that code in the future in a non-Http environment. Throw your own ItemNotFound exception if you require at least one item and handle that exception in the Controller, or return null and handle that.

Moo
+1  A: 

Never throw an HttpException from a repository...it's the wrong level of abstraction. If you don't want you're repository to return null, do something like this:

// CONTROLLER
public ActionResult Edit(int categoryId, int id)
{
    try {
       Product target = Products.GetById(id);
    }
    catch(ProductRepositoryException e) {
       throw new HttpException(404, "Product not found")
    }

    return View("Edit", target);
}

// REPOSITORY
public Product GetById(int id)
{
    Product target = context.Products.FirstOrDefault(x => x.productId == id);
    if (target == null) throw new ProductRepositoryException();

    return target;
}

You're repository should not know anything about HTTP, but you're controller can know about the repository. So you throw a repository exception from the repository, and "translate" that into an HTTP Exception in the controller.

blockhead
But then I have to create custom exceptions :(?
ebb
Yes you do. And that's what you *should* do.
blockhead
I'll just create a custom exception named "NotFoundException" then. Thanks for the answer :)
ebb