Not Found returning 405

Discussions relating to the REST API of Jiwa 7.

Not Found returning 405

Postby SBarnes » Tue Nov 17, 2020 4:34 pm

I have the code below to return an image for a route it works fine but when you give it a bad inventory ID it is returning a 405 instead of a 404, it is definitely producing the RecordNotFoundException but just the wrong status code any ideas how to resolve this?


Code: Select all
         [Authenticate]
         [AddHeader(ContentType = "image/png")]
         public byte[] Get( ImageRequest request)
         {

            JiwaApplication.Manager manager = this.SessionAs<JiwaAuthUserSession>().Manager;
            JiwaFinancials.Jiwa.JiwaInventory.Inventory inv =  manager.BusinessLogicFactory.CreateBusinessLogic<JiwaFinancials.Jiwa.JiwaInventory.Inventory>(null);
            try
            {
               inv.Read(request.InventoryID);
            }
            catch(Exception ex)
            {
               
               throw new JiwaApplication.Exceptions.RecordNotFoundException("Product not found for " + request.InventoryID);
            }
            

            return inv.Picture;
         }
Regards
Stuart Barnes
SBarnes
Shihan
Shihan
 
Posts: 1617
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 175

Re: Not Found returning 405

Postby Mike.Sheen » Tue Nov 17, 2020 5:05 pm

Hi Stuart,

Does the response header contain an Allow field? a 405 response is supposed to have an Allow field which contains a list of allowed operations on that route. So, I think a 405 should be returned is you're trying to POST to a route which only knows how to GET on that, or something like that.

How we return a 404 when a RecordNotFoundException is encountered is via some exception mapping we add in the Configure method of the REST API plugin:

Code: Select all
AppHost.Config.MapExceptionToStatusCode.Add(typeof(JiwaApplication.Exceptions.RecordNotFoundException), 404);
AppHost.Config.MapExceptionToStatusCode.Add(typeof(JiwaApplication.Exceptions.LicencingException), 403);
AppHost.Config.MapExceptionToStatusCode.Add(typeof(JiwaApplication.Exceptions.PermissionDeniedException), 403);
AppHost.Config.MapExceptionToStatusCode.Add(typeof(JiwaApplication.Exceptions.ConcurrencyConflictException), 409);
AppHost.Config.MapExceptionToStatusCode.Add(typeof(JiwaApplication.Exceptions.RecordInUseException), 409);
AppHost.Config.MapExceptionToStatusCode.Add(typeof(JiwaFinancials.Jiwa.JiwaODBC.Exceptions.BadLoginException), 401);


If you've not explicitly gone and added your own mappings or modified ours, then it's likely as I said earlier - you've added a GET operation but the client is performing a POST or something other than a GET. Make sure the AppHost.Routes.Add you have for the route correctly passes the right verb - eg:

Code: Select all
AppHost.Routes.Add(typeof(DebtorAPIKeyDebtorGETRequest), "/Debtors", "GET", "Retrieves a debtor for a API Key authenticated customer.", "");

The "GET" above is the verb .
Mike Sheen
Chief Software Engineer
Jiwa Financials

If I do answer your question to your satisfaction, please mark it as the post solving the topic so others with the same issue can readily identify the solution
User avatar
Mike.Sheen
Overflow Error
Overflow Error
 
Posts: 2440
Joined: Tue Feb 12, 2008 11:12 am
Location: Perth, Republic of Western Australia
Topics Solved: 755

Re: Not Found returning 405

Postby Mike.Sheen » Tue Nov 17, 2020 5:11 pm

Oh, and you shouldn't do this :

Code: Select all
catch(Exception ex)


You really should only catch the RecordNotFoundException - if a different exception is encountered (like maybe the SQL Server is unreachable) you don't want to return a 404 so you want to:

Code: Select all
catch(JiwaApplication.Exceptions.RecordNotFoundException(ex)
{
    throw new JiwaApplication.Exceptions.RecordNotFoundException("Product not found for " + request.InventoryID);
}


And given that you're not adding much value to the exception with your own throw (the caller should already know the InventoryID as they provided it to you) you can probably dispense with the try catch block altogether :)
Mike Sheen
Chief Software Engineer
Jiwa Financials

If I do answer your question to your satisfaction, please mark it as the post solving the topic so others with the same issue can readily identify the solution
User avatar
Mike.Sheen
Overflow Error
Overflow Error
 
Posts: 2440
Joined: Tue Feb 12, 2008 11:12 am
Location: Perth, Republic of Western Australia
Topics Solved: 755

Re: Not Found returning 405

Postby SBarnes » Tue Nov 17, 2020 5:22 pm

Not I haven't added any mappings for exceptions is was because of the ones you have in the main plugin that I changed to the RecordNotFoundException instead of Exception, could it be because of the following line?

Code: Select all
 [AddHeader(ContentType = "image/png")]


But it is definitely getting the RecordNotFoundException as that's even showing up in Postman and it is definitely doing a GET.

Routes added as


Code: Select all
AppHost.Routes.Add(typeof(ImageRequest), "/Images/GetImage", "GET", "Get the image for the inventory.", "");
         
AppHost.Routes.Add(typeof(ImagePartNoRequest), "/Images/GetImageFromPartNo", "GET", "Get the image for the inventory based upon part no.", "");
Regards
Stuart Barnes
SBarnes
Shihan
Shihan
 
Posts: 1617
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 175


Return to REST API

Who is online

Users browsing this forum: Google [Bot] and 1 guest

cron