let's say i have a method that logins in;
public async Task<IActionResult> Login()
{
try
{
//my codes..
}
catch(Exception exp)
{
_sLogger.Slack(exp)
return BadRequest();
}
}
i have tested all controllers and methods but i can't test the catch block? i can't throw a exception, how can i do that?
i have tried like this but that doesn't work for me:
public void_WithInvalidData_ThenBadRequest()
{
authController.UnAuthrorize();
var result=(BadRequestResult)authController.Login();
Assert.True(result.StatusCode == (int)HttpStatusCode.BadRequest);
authController.Authorize();
}
Use following code
public async Task<IActionResult> Login()
{
try
{
if (conditions) throw new Exception($"Message"); // throw an exception
}
catch(Exception exp)
{
_sLogger.Slack(exp)
return BadRequest();
}
}
Related
What does the below code block mean:
catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
{
return NotFound();
}
Full sample:
// PUT: api/TodoItems/5
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPut("{id}")]
public async Task<IActionResult> UpdateTodoItem(long id, TodoItemDTO todoItemDTO)
{
if (id != todoItemDTO.Id)
{
return BadRequest();
}
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
todoItem.Name = todoItemDTO.Name;
todoItem.IsComplete = todoItemDTO.IsComplete;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
{
return NotFound();
}
return NoContent();
}
This is called an exception filter clause. It is normally used like this:
// without exception filters:
try
{
var file = new StreamReader(myInputStream);
// ....
}
catch (IOException x)
{
// Handle error
}
catch (UnauthorizedAccessException x)
{
// Handle error (same as above)
}
catch (SocketException x)
{
// Handle error (again, same as above)
}
// etc., etc...
// Instead, one can write
try
{
var file = new StreamReader(myInputStream);
// ....
}
catch (Exception x) when (x is SocketException || x is UnauthorizedAccessException || x is IOException)
{
// Handle all expected exception types in one handler
}
I have never seen it being used as in your example. And I'm not sure it is used correctly. What it does is that it only enters the catch clause when TodoItemsExists returns false. That means, on the other hand, that if a DbUpdateConcurrencyException is thrown and TodoItemsExists returns true, the catch handler is not invoked and the exception falls trough, eventually crashing the server task.
I'm not sure about the actual requirement, but I think the following is intented instead:
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoItemExists(id))
{
return NotFound();
}
}
return NoContent();
So this will return the appropriate error message to the caller (either NotFound() or NoContent()) when the exception is thrown.
The condition in the when clause can be used to do an additional test whether the handler should be invoked.
I want to return IActionResult compatible UnprocessableEntity - HttpStatusCode (422) from below catch block the way I am returning `Ok' (200) from try block.
It's giving cast error for below code, What I can do here as I don't want to return 500.
Cannot implicitly convert type 'System.Net.HttpStatusCode' to 'Microsoft.AspNetCore.Mvc.IActionResult'
public IActionResult GetMe()
{
try
{
return Ok();
}
catch (Exception exception)
{
//cast error
// return HttpStatusCode.UnprocessableEntity;
}
}
I think you want return this
public IActionResult GetMe()
{
try
{
return Ok();
}
catch (Exception exception)
{
return UnprocessableEntity();
}
}
I currently have the below code which I thought would work however I am receiving a "HttpControllerContext.Configuration must not be null" error when I create the Ok result. The goal is to be able to call any function in a controller in one line to keep my controllers clean. Such as "return ApiUtilities.TryCatch(() => _someService.Get(id));"
I only have access to 'Ok()', "NotFound()" and "InternalServerError()" because the ApiUtilities Class inherits from ApiController
public IHttpActionResult TryCatch<T>(Func<T> operation)
{
try
{
if (ModelState.IsValid)
{
var result = operation();
return Ok(result);
}
}
else
{
return BadRequest();
}
}
catch (Exception error)
{
return InternalServerError();
}
Edit:
My controller looks like this
public class PageController : ApiController
{
private ISomeService _someService;
private ApiUtilities _apiUtilities;
public PageController(ISomeService someService)
{
_someService= someService;
_apiUtilities = new ApiUtilities();
}
[Route("api/page")]
public IHttpActionResult Get([FromBody]string url)
{
return _apiUtilities.TryCatch(() => _someService.Get(url));
}
}
Below is the update I've made based on a Friend's suggestion. I've removed the inheritance on the ApiController. I've also returned the same models the Ok, BadRequest and NotFound functions generate using the context of the current api.
public static class ApiUtilities
{
public static IHttpActionResult TryCatch(Action action, ApiController apiController)
{
try
{
if (apiController.ModelState.IsValid)
{
action();
return new OkResult(apiController);
}
else
{
return new BadRequestResult(apiController);
}
}
catch (Exception error)
{
return new NotFoundResult(apiController);
}
}
public static IHttpActionResult TryCatch<T>(Func<T> operation, ApiController apiController)
{
try
{
if (apiController.ModelState.IsValid)
{
var result = operation();
return new OkNegotiatedContentResult<T>(result, apiController);
}
else
{
return new BadRequestResult(apiController);
}
}
catch (Exception error)
{
return new NotFoundResult(apiController);
}
}
}
I have this block of code:
[HttpDelete("{id}")]
public async Task<IActionResult> Delete([FromBody] MonitorsDeleteRequest request)
{
if (request == null)
{
return BadRequest("Request could not be parsed.");
}
if (request.MonitorId == Guid.Empty)
{
return BadRequest("Query Monitor Id is required.");
}
try
{
await monitoringService.RemoveMonitorAsync(
new RemoveMonitorRequest()
{
MonitorId = new MonitorId(request.MonitorId)
});
return Accepted();
}
catch (Exception ex)
{
logger.LogError($"[{Request.Path.Value}]: {ex.ToString()}");
return StatusCode(500, ex.Message);
}
}
The MonitorId that is inside the RemoveMonitorRequest method (on the left of the equal sign) is underlined in red - Intellisense says "RemoveMonitorRequest does not contain a definition for MonitorId."
Just FYI, the other MonitorId earlier in the code has no Intellisense error.
What can I do to remedy this?
I'm not able to access to my delete method of my api rest.
If i write the method like this it work:
[Route("api/Document/{documentId:int}")]
[HttpDelete]
public IHttpActionResult Delete([FromUri]int documentId,[FromBody] int [] documentsId)
{
try
{
documentCtrl = documentCtrl ?? new DocumentCtrl();
return Ok(documentCtrl.Delete(documentsId));
}
catch (DocumentNotFoundException)
{
return NotFound();
}
catch (Exception)
{
return InternalServerError();
}
}
It works, but if i put:
[Route("api/Document/MassiveDelete")]
[HttpDelete]
public IHttpActionResult MassiveDelete([FromBody] int[] ids)
{
try
{
documentCtrl = documentCtrl ?? new DocumentCtrl();
return Ok(documentCtrl.MassiveDelete(ids));
}
catch (DocumentNotFoundException)
{
return NotFound();
}
catch (Exception)
{
return InternalServerError();
}
}
I don't have acces, any ideas what could it be?
This is my request code:
DeleteDocument(id: number): Observable<boolean> {
return this._httpService.delete(AppModule.service + 'Document/' + id, AppModule.options)
.map((response: Response) => <boolean>response.json())
.catch(this.handleError);
}//This work if i want to delete one
DeleteDocuments2(ids:Array<number>):Observable<boolean>{
AppModule.options.body=ids;
return this._httpService.delete(AppModule.service + 'Document/MassiveDelete', AppModule.options)
.map((response: Response) => <boolean>response.json())
.catch(this.handleError);
}
You cannot send two parameters in your Api, you need to createa custom class like follow and send as follows,
MyCustomRequest {
public int[] documentIds;
public int documentId;
}
and then,
public IHttpActionResult MassiveDelete([FromBody] MyCustomRequest request)
you can access it as,
request.documentIds;
request.documentId;