Send message with actionresult - c#

I need to return the server error from azure functions.
Now I implement the same using InternalServerErrorResult(). It only sends the error code and no response/message can be sent with this function.
How to implement an exception handler where the error code and message can be sent together using actionresult in azure functions
current implementation
catch (Exception ex)
{
log.LogInformation("An error occured {0}" + ex);
//json = new Response(ex.StackTrace, AppConstants.ErrorCodes.SystemException).SerializeToString();
return (ActionResult)new InternalServerErrorResult();
}
this returns with an empty response in postman with error 500

Note that this is from Microsoft.AspNetCore.Mvc namespace:
var result = new ObjectResult(new { error = "your error message here" })
{
StatusCode = 500
};
Based on configured formatters it will return serialized object to client.
For JSON (it's default) it will return following:
{ "error" : "your error message here" }

To send a message with the status code you can use return StatusCode(httpCode, message), which is an ObjectResult.
For example:
return StatusCode(500, "An error occurred");
You can also pass an object (example using HttpStatusCode enum):
return StatusCode((int)HttpStatusCode.InternalServerError, json);

Related

how to set response when i am using IActionResult in return type with error message?

when try block send error to catch block it throw and response I got at frontend was {status:'error',error:500}.
Please explain me what is going when I Re-throw in catch block.
Is .NET is set response when I re-throw?
I want to set status message. how can I do?
I want to set status message. how can I do?
Well, you can bind custom status inside BadRequest() or Any other response class result. For instance:
public async Task<IActionResult> DownloadAttachedFile()
{
try
{
//Your code
}
catch (Exception ex)
{
return BadRequest(new { StatusMessage = "Your Messaage", StatusCode = 400 });
}
}
Note: Here StatusMessage, you can even concat your ex message as well. Can introduce new custom error class. You can also skip StatusCode = 400 because BadRequest itself will return that code but if you want to fetch easily from your frontend you can set as well.
Output:
In your frontend you would get the response as following:
{
"statusMessage": "Your Messaage",
"statusCode": 400
}
In addition, you can always customize your response class based on your requirement.

Angular catchError firing unexpectedly when received StatusCode object from c#

I have an API call that is working on the C# backend, but the Angular front-end seems to take the C# reply as an error. Note the text of the object is 'comment added' indicating that a 200 OK response was sent back. Why is the catchError function triggering?
C# method:
[HttpPost("AddComments")]
public ActionResult<string> AddComment(BillingComments b)
{
try
{
return StatusCode(200, "comment added");
}
catch (Exception e)
{
return StatusCode(500, "error adding comment");
}
}
Angular method:
submitComment(newComment: BillingComments): any {
return this.http.post('/api/BillingLg/AddComments', newComment)
.pipe(catchError(this.appSvc.handleError<string>('submitComment', 'comment submitting err')));
}
Error returned by appSvc.handleError:
Service error: submitComment failed
Msg: Http failure during parsing for http://localhost:49975/api/BillingLg/AddCommentsStatus: 200Detail: {"error":{},"text":"comment added"}Text: OK & return type specified (failed gracefully)
Angular by default parse the responses from APIs to Object, so by default, it expects JSON string to be returned from the API.
So you have two options, either to return a JSON instead of the string (Which is recommended), something like
return StatusCode(200, "{\"status\": \"comment added\"}");
Or you can make the HttpClient expects a string to be returned:
this.http.post('/api/BillingLg/AddComments', newComment, {responseType: 'text'})
.pipe(catchError(this.appSvc.handleError<string>('submitComment', 'comment submitting err')));

Exception in server by android retrofit

I'm trying to throw an exception on my server so that my application on Android gets this exception and shows it, I inquired about this service at the postman, the answer I can get, was the message I send from the server "the code is not found in bd. " but in the application only the error "An error has occurred" is displayed.
this is the service and the throw:
internal TDDC InfoTD()
{
throw new Exception("the code is not found in bd");
}
this is the postman
{
"Message": "An error has occurred.",
"ExceptionMessage": "the code is not found in bd",
"ExceptionType": "System.Exception",
And in android
String errorResponse = response.errorBody().string();
JSONObject object = new JSONObject(errorResponse);
if (object.has("Message"))
message = String.valueOf(object.get("Message"));
¿ how i can get the message in "ExceptionMEssage" in android application ?, in this I use Retrofit 2
Its a bad practice to implemt or parse network error responses on your each service call.
Instead you can centralize a catch or network error like this.
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
okhttp3.Response response = chain.proceed(request);
// check your network responses here
if (response.code() == 500) {
startActivity(
new Intent(
ErrorHandlingActivity.this,
ServerIsBrokenActivity.class
)
);
return response;
}
return response;
}
})
.build();

How to get normal/custom error response for an exception from an Action returning Stream in ServiceStack?

I have been venturing in the ServiceStack's documentation regarding an issue with throwing Exceptions from an Action that returns a Stream.
The issue is that while all the other Actions in my service return beautiful errors like:
{
"ResponseStatus": {
"ErrorCode": "ArgumentException",
"Message": "Unable to load data",
"StackTrace": "[GetData: 7/11/2016 1:02:11 PM]:\n[REQUEST: {Token:asdf,Id:1}]\nServiceStack.HttpError: Unable to load codes from token ---> System.ArgumentException: Unable to load codes from token.............(abridged)
}
}
There is an Action with the return type as Stream from which, regardless of the type of exception returned, the http client receives the following response:
With the handler (as per the SS documentation):
Error: ArgumentNullException: As result 'ErrorResponse' is not a supported responseType, a defaultAction must be supplied
Parameter name: defaultAction
And without any handlers:
'no content'
400
Any help will be greatly appreciated.
Sample Code-->
Here is an example of the Action:
[AddHeader(ContentType = "application/pdf")]
public Stream Get(GetPdfRequest request)
{
throw new NotImplementedException("FAKE EXCEPTION");
}
and in the APPHOST's Configure() method:
this.UncaughtExceptionHandlers.Add((req, res, operationName, ex) =>
{
var logger = LogManager.GetLogger(GetType());
logger.Error("Unhandled error in API during request binding.", ex);
res.Write("Error: {0}: {1}".Fmt(ex.GetType().Name, ex.Message));
res.EndRequest(skipHeaders: true);
});
this.ServiceExceptionHandlers.Add((httpReq, request, exception) =>
{
var logger = LogManager.GetLogger(GetType());
logger.Error("Unhandled error in API.", exception);
//call default SS exception handler
return DtoUtils.CreateErrorResponse(request, exception);
});
Here is a screenshot of what I see on the Swagger Rest client when the above Action is called.
The issue is due to being unable to serialize the ErrorResponse DTO into the unregistered "application/pdf" ContentType.
I've just added a fallback to use the Config.DefaultContentType for serializing errors in unregistered Content Types in this commit, available from v4.0.61 that's now available on MyGet.
A workaround for prior versions of ServiceStack is instead of using the [AddHeader] Request Filter Attribute, to instead set the Content-Type in the Service implementation just before you serialize, so any Exceptions are thrown before Response ContentType is set, e.g:
public class ErrorStream {}
public class ErrorStreamService : Service
{
public Stream Any(ErrorStream request)
{
if (!IsValid(request))
throw new NotImplementedException("Exception in Stream Response");
base.Request.ResponseContentType = "application/pdf";
return PdfAsStream(request);
}
}
Which throws a Typed Exception when using a Service Client:
try
{
var response = client.Get<Stream>(new ErrorStream());
Assert.Fail();
}
catch (WebServiceException ex)
{
Assert.That(ex.IsAny400());
Assert.That(!ex.IsAny500());
Assert.That(ex.ErrorCode, Is.EqualTo("NotImplementedException"));
Assert.That(ex.StatusCode, Is.EqualTo((int)HttpStatusCode.MethodNotAllowed));
}
Also UncaughtExceptionHandlers is only for handling Exceptions thrown outside of a Service, exceptions that occur within a Service are instead handled by ServiceExceptionHandlers instead, but be careful when modifying the default Exception handling behavior as you can invalidate the typed Exception handling on the client.

How to return error message from Catch block. Right now empty is returned

My sample code of ApiKey validation is given below (I am using MVC4 web api RC):
public class ApiKeyFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext context)
{
//read api key from query string
string querystring = context.Request.RequestUri.Query;
string apikey = HttpUtility.ParseQueryString(querystring).Get("apikey");
//if no api key supplied, send out validation message
if (string.IsNullOrWhiteSpace(apikey))
{
var response = context.Request.CreateResponse(HttpStatusCode.Unauthorized, new Error { Message = "You can't use the API without the key." });
throw new HttpResponseException(response);
}
else
{
try
{
GetUser(decodedString); //error occurred here
}
catch (Exception)
{
var response = context.Request.CreateResponse(HttpStatusCode.Unauthorized, new Error { Message = "User with api key is not valid" });
throw new HttpResponseException(response);
}
}
}
}
Here problem is with Catch block statement. I Just wanted to send custom error message to user. But nothing is sent. It displays a blank screen
However, the statement below is working well and sends out the validation error message correctly:
if (string.IsNullOrWhiteSpace(apikey))
{
var response = context.Request.CreateResponse(HttpStatusCode.Unauthorized, new Error { Message = "You can't use the API without the key." });
throw new HttpResponseException(response);
}
Is there anything that i am doing wrong.
I was having the same issue in the exact same scenario. However, in this scenario, you need to return some content in your response to be shown and not really throw the exception. So based on this, I would change your code to the following:
catch (Exception)
{
var response = context.Request.CreateResponse(httpStatusCode.Unauthorized);
response.Content = new StringContent("User with api key is not valid");
context.Response = response;
}
So with this change you are now returning your response, with content that will displayed in place of the blank screen.

Categories