I'm kind of not sure as to where to catch an application and any other unexpected exception, but i do want to show on the front end which exception occurred either an application or any other exception.
If i just 'throw' from service manager then it will be catched in the controller, but what if there was an exception in the service manager and the controller?
This also seems verboose.
This is my service manager where I'm calling an API.
public async Task<int> CreateCategory(CategoryViewModel model)
{
logger.LogInformation("In {service}, Creating {CategoryModel}", nameof(CategoryServiceManager), model.ToString());
try
{
model.Guard(model.ToString());
int categoryId = await apiClient.PostAsync<int, CategoryViewModel>("Category", model);
return categoryId;
}
// Guard wil throw
catch (ApplicationException ex)
{
logger.LogError("Exception thrown for {model}: {Message}, {Stacktrace}", model.ToString(),ex.Message, ex.StackTrace);
throw new ApplicationException($"Exception thrown in service when creating category: {ex.Message}");
}
catch (Exception ex)
{
logger.LogError("Unexpected error thrown in service when creating a category : {Message}, {Stacktrace}", ex.Message, ex.StackTrace);
throw new Exception("Unexpected error thrown in service when creating a category");
}
}
This is the Guard extension used in the service manager.
public static class GuardExtensions
{
public static void Guard(this string input, string inputName)
{
if (string.IsNullOrEmpty(input))
{
throw new ApplicationException($"{inputName} must be provided");
}
}
public static void Guard(this object input, string inputType)
{
if (input == null)
{
throw new ApplicationException($"{inputType} must be provided");
}
}
}
This is the controller where I'm using the the service manager.
public async Task<IActionResult> Create(CategoryViewModel model)
{
logger.LogInformation("In {controller}, Creating {CategoryViewModel}", nameof(CategoryController), model.ToString());
try
{
if (ModelState.IsValid)
{
int createdCategoryId = await categoryService.CreateCategory(model);
List<CategoryPictureViewModel> categoryPictureViewModels = new List<CategoryPictureViewModel>();
foreach (int picId in TransformTypes.SplitStringIntoListOfInt(model.uploadedImageIds))
{
categoryPictureViewModels.Add(new CategoryPictureViewModel
{
CategoryId = createdCategoryId,
PictureId = picId
});
//model.CategoryPictures.ToList().Add(new CategoryPictureViewModel
//{
// CategoryId = createdCategoryId,
// PictureId = item
//});
}
int res = await categoryPictureService.CreateCategoryPictureAsync(categoryPictureViewModels);
return RedirectToAction(nameof(Index));
}
}
catch (ApplicationException ex)
{
logger.LogError("In {controller}, Creating category: {Message}, {Stacktrace}", nameof(CategoryController), ex.Message, ex.StackTrace);
throw new ApplicationException($"Exception thrown controller when creating category: {ex.Message}");
}
catch (Exception ex)
{
logger.LogError("Unexpected error in {controller} when creating category: {Message}, {Stacktrace}", nameof(CategoryController), ex.Message, ex.StackTrace);
throw new Exception($"Unexpected error in controller when creating category: {ex.Message}");
}
return StatusCode(StatusCodes.Status422UnprocessableEntity);
}