locked
pass custom error from web api to client RRS feed

  • Question

  • User369345748 posted

    I am running a web api 2.2  app,  & getting it to throw an exception.   Debugging the api,  I can see it is throwing the error with the correct custom error message. Eg "Only Zoo keepers can feed the zebras"  ( Nice and specific) , but by the time I get back to the client , the specific error is replaced by a generic 500 server error.  How do I make the custom error persist: 

    with res set as follows

    var res = "Only Zoo keepers can feed the zebras";

    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest)
    {
    Content = new StringContent(res),
    ReasonPhrase = res,
    };

    I have tried throwing this error through both 

    throw new HttpResponseException(response);

    AND 

    actionExecutedContext.Response = response;

    I run this from a webclient() in a separate app,  which has a global error handler in global.asax 

    protected void Application_Error(object sender, EventArgs e)

        { Exception exception = Server.GetLastError();

      logger.info (exception.Message);

      logger.info (exception.InnerException);

    & fiddler shows nothing for the api calls.  I dont know if this is an issue with how it trigger the error  from the api, or if its how the client is handling it 

    Friday, June 15, 2018 11:12 AM

Answers

  • User-369506445 posted

    one of the above links was with C#,

    anyway, please do step by step

    first , create a class called NotImplExceptionFilterAttribute

      public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute
        {
            public override void OnException(HttpActionExecutedContext context)
            {
                // this a test 
                // tou can check your custom error
                 if (context.Exception.Message.Equals("not fond"))
                {
    // for example here I return 403 erorr context.Response = new HttpResponseMessage(HttpStatusCode.Forbidden); } } }

    then add below code in your Global.asax

     protected void Application_Start()
    {

    GlobalConfiguration.Configuration.Filters.Add( new NotImplExceptionFilterAttribute());

    finally create an API controller below like :

    public class ValuesController : ApiController
        {
            // GET api/values/5
            public string Get(int id)
            {
                throw new Exception("not fond");
                return "value";
            }
        }

    now when you call your API you get below

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, June 18, 2018 10:09 AM
  • User369345748 posted

    I have found the answer.  It is to do with how the client calls the service,  & handles errors from the api.  The default exception event is not granular enough to store all the detail from a web exception event thrown by the api.  Even a web exception requires some drilling down and recasting of the returned data, before you can get anything useful. 

    But this code works ( NB ProcessException is my custom error handler in the Client  - it copies an error to a log & directs people on to a customised friendly error screen, but any UI error process should work 

    try{

     return Wclient.DownloadString(myServiceUrl);

    }

    catch (WebException wex)  {

      throw new ProcessException((((HttpWebResponse)wex.Response).StatusDescription));

     }

     catch (Exception ex)  {

      throw new ProcessException(ex.Message);

     }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 19, 2018 10:21 AM
  • User-1034726716 posted

    I'm not exactly sure if I follow you correctly, but if you trying to handle exceptions build your own custom response then you could implement a filter in your Web API. Here's a recent article that I wrote that might give you some ideas on how to implement your needs: ASP.NET Core and Web API: A Custom Wrapper for Managing Exceptions and Consistent Responses 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, June 27, 2018 2:50 AM

All replies

  • User369345748 posted

    Hi Vahid,  

    Thank you very much for replying.  I forget to mention that I am using C# , so unfortunately I dont think the VB samples will help alot.  & I already referenced the other two to build the API.  I am also trying this through a dedicated try catch in the C# controller, where I get the same result. I have also tried a version of the call through Angular.  The Angular version  retains the original error.   

    Unfortunately the location of the call is such that an angular solution is not viable, but it does suggest that the issue may be in my WebClient C# call.   Any ideas?

    I have also noticed that the c#  webclient version of the call  'forgets' the httpreferrer.  The web API has its own location in these fields at this time.  -So if my api is at localhost:1234,, & my webclient is being run from localhost:6789.  Then stepping through the api code , I see the referrer as either null or localhost:1234 when I am running it from localhost:6789 webclient, but it is localhost:6789 , when I run it from localhost:6789 Angular JS

    Thanks again Richard

     

    Monday, June 18, 2018 9:23 AM
  • User-369506445 posted

    one of the above links was with C#,

    anyway, please do step by step

    first , create a class called NotImplExceptionFilterAttribute

      public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute
        {
            public override void OnException(HttpActionExecutedContext context)
            {
                // this a test 
                // tou can check your custom error
                 if (context.Exception.Message.Equals("not fond"))
                {
    // for example here I return 403 erorr context.Response = new HttpResponseMessage(HttpStatusCode.Forbidden); } } }

    then add below code in your Global.asax

     protected void Application_Start()
    {

    GlobalConfiguration.Configuration.Filters.Add( new NotImplExceptionFilterAttribute());

    finally create an API controller below like :

    public class ValuesController : ApiController
        {
            // GET api/values/5
            public string Get(int id)
            {
                throw new Exception("not fond");
                return "value";
            }
        }

    now when you call your API you get below

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, June 18, 2018 10:09 AM
  • User369345748 posted

    Hi Vahid

    Thanks again for you response, & the detail.  My subsequent testing of running my API directly through the browser ( similar to your api/values/5 example) does return the correct custom error message.  In my case , I also tested the API in Angular, & I also got back the correct message. 

    The problem seems to be when I use a Webclient.Downloadstring(), & unfortunately this is in a server side operation

    Thanks again Richard

    Tuesday, June 19, 2018 9:38 AM
  • User-369506445 posted

    hi Richard

    I tried it with <g class="gr_ gr_6 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace" id="6" data-gr-id="6">Webclient</g><g class="gr_ gr_12 gr-alert gr_gramm gr_inline_cards gr_run_anim Style replaceWithoutSep" id="12" data-gr-id="12">.<g class="gr_ gr_7 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del multiReplace" id="7" data-gr-id="7">Downloadstring</g></g> and I got my custom response and it was correct

    for example in the last example I generated a Forbidden status code like below

    public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute
        {
            public override void OnException(HttpActionExecutedContext context)
            {
                 if (context.Exception.Message.Equals("not fond"))
                {
                    context.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
                }
            }
        }

    and when I called it with <g class="gr_ gr_8 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace" id="8" data-gr-id="8">Webclient</g>.<g class="gr_ gr_9 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace" id="9" data-gr-id="9">Downloadstring</g>

    Tuesday, June 19, 2018 10:17 AM
  • User369345748 posted

    I have found the answer.  It is to do with how the client calls the service,  & handles errors from the api.  The default exception event is not granular enough to store all the detail from a web exception event thrown by the api.  Even a web exception requires some drilling down and recasting of the returned data, before you can get anything useful. 

    But this code works ( NB ProcessException is my custom error handler in the Client  - it copies an error to a log & directs people on to a customised friendly error screen, but any UI error process should work 

    try{

     return Wclient.DownloadString(myServiceUrl);

    }

    catch (WebException wex)  {

      throw new ProcessException((((HttpWebResponse)wex.Response).StatusDescription));

     }

     catch (Exception ex)  {

      throw new ProcessException(ex.Message);

     }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 19, 2018 10:21 AM
  • User-1034726716 posted

    I'm not exactly sure if I follow you correctly, but if you trying to handle exceptions build your own custom response then you could implement a filter in your Web API. Here's a recent article that I wrote that might give you some ideas on how to implement your needs: ASP.NET Core and Web API: A Custom Wrapper for Managing Exceptions and Consistent Responses 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, June 27, 2018 2:50 AM