I am trying to implement the log in service for an application, and I would like to throw an exception if the response status code is not equal to 200. I am using Alamofire as HTTP networking library.
static func loginWithUsername(username: String, andPassword password: String) throws {
let action = "SmartShoppers/login"
let url = baseUrl + action
Alamofire.request(.POST, url, parameters: ["username": username, "password": password])
.response { request, response, data, error in
if response?.statusCode != 200 {
throw ServiceError.LogInError
}
}
}
This is the ServiceError enum definition:
enum ServiceError: ErrorType {
case LogInError
}
What I want to do deal this exception when it is thrown in a function which is called when a button is pressed. This function is in the ViewController class associated with the ViewController that contains that button. The code that is going to be executed is:
do {
try Service.loginWithUsername(username, andPassword: password)
} catch {
// SHOW AN ALERT MESSAGE
}
Why am I receiving the message Cannot call value of non-function type 'NSHTTPURLResponse'? Is it the correct way to implement this service? If not please help me.
The closure that you are passing to the response method does not include throws in its signature, so you will not be able to throw an exception from within it.
IMO this is not a case where you would want to throw an exception, anyways - a non-200 response code is not an exceptional error / failure, and I wouldn't try to use an exception here as a means of control flow.
Related
Hi I am new to the dart and flutter framework.
I am throwing error like below from my service class where i am calling the API.
if(res["status"]!=200) throw new Exception("Invalid User");
and receiving in presenter class like below and printing
.catchError((Object error){
print(error);
});
I am expecting the result as "Invalid User", but am getting with additional word like "Exception: Invalid User". Can you please explain me why this additional word 'Exception' is coming? and how can i get only the string which i am passing.
Surprisingly that's how written in exception toString code.
String toString() {
if (message == null) return "Exception";
return "Exception: $message"; // your message will be appended after exception.
}
If you want to avoid this then you have to create custom exception like below:
class HttpException implements Exception {
final String message;
HttpException(this.message); // Pass your message in constructor.
#override
String toString() {
return message;
}
}
You can use the message property of the Exception object
.catchError((error){
print(error.message);
});
This should output Invalid User
I hope this is what you are looking for.
Quick solution:
.catchError((error){
print(
error.toString().substring(11)
);
});
You cut the first 11 message chars, that is, "Exception: ".
You can create an extension function in dart as
extension FormattedMessage on Exception {
String get getMessage {
if (this.toString().startsWith("Exception: ")) {
return this.toString().substring(11);
}else {
return this.toString();
}
}
}
After that you can simply call
exception.getMessage;
to get your extension message without having to implement the Extension class or show the user how the exception is being substring.
Asp.Net Web API Odata Controller Action:
public async Task<IHttpActionResult> Post(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Products.Add(product);
await db.SaveChangesAsync();
return Created(product);
}
Odata client code:
(Odata v4 client code generator v4)
static void AddProduct(Default.Container container, ProductService.Models.Product product)
{
container.AddToProducts(product);
var serviceResponse = container.SaveChanges();
foreach (var operationResponse in serviceResponse)
{
Console.WriteLine("Response: {0}", operationResponse.StatusCode);
}
}
I would like to handle exception in a proper way inside AddProducts() Method while saving the changes.
How can I catch process the ModelState error which is sent from server return BadRequest(ModelState);?
Finally I just want to show the error message to the end uses which was sent from server.
Example:
"Product category is required."
What is the use of ODataException class? Will this help me?
Please help me.
if I understood well, you want to intercept that the ModelState is not valid, and customize the OData error that is shown to the user.
If you just want that the errors of the invalid model show up in the returned payload, you can use:
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
If you want to fully control the exceptions handling and messages shown, I'd suggest several action points for you to accomplish this:
Intercept ModelState is not valid: you can do this with a custom ActionFilterAttribute. In there, you can override the method OnActionExecuting(HttpActionContext actionContext). You can access the ModelState through actionContext.ModelState, check if it is valid, check the fields that have errors, check the nature of these errors and the generated messages for these errors, etc. The ModelState may be not valid for different reasons, like different types than the expected, not meet requirements specified by DataAnnotations, etc. You can check more on Model validation in here. For your case, I guess the Product entity will have a Required data annotation in the Category field.
After checking all errors, you can throw a custom Exception with the error/list of errors with the messages you want. This is necessary to later intercept your custom exception and be able to return your custom message in the error payload.
Intercept your custom exception: create a custom ExceptionFilterAttribute to intercept your thrown exceptions. Overriding the
OnException(HttpActionExecutedContext filterContext) you will have access to the exception, and inspecting it you will be able to build your proper OdataError:
In here you should return the HttpResponseMessage with the BadRequest http status code and the created ODataError as a payload. As an example of very simple code (you can see that it would depend on how you build your custom exception):
public override void OnException(HttpActionExecutedContext filterContext)
{
Exception ex = filterContext.Exception;
HttpRequestMessage currentRequest = filterContext.Request;
if (filterContext.Exception.GetType() == typeof(YourCustomValidationException))
{
var oDataError = new ODataError()
{
ErrorCode = "invalidModel",
Message = "Your model is not valid.",
InnerError = new ODataInnerError()
{
TypeName = ex.TheEntityThatHasErrors
},
};
foreach (var validationError in ex.ValidationErrors)
{
oDataError.InnerError.Message += validationError + ", ";
}
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
response.RequestMessage = currentRequest;
response.Content = new StringContent(JsonConvert.SerializeObject(oDataError));
filterContext.Response = response;
}
}
Finally, you will have to setup the custom ActionFilterAttribute and the custom ErrorFilterAttribute to be used each time that a request reach your controller. You can decorate your actions, controllers, or you can set the filters for all your API controllers in the WebApiConfig, with config.Filters.Add(...);
You can find more information about all of this in here. In the end, the error and exception handling is the same for ASP.Net Web API, with or without OData; difference is that if you have an OData API, you should return errors in OData style.
Hope all this info is understandable and helps you somehow.
I was trying to research the problem, but failed, therefore am asking this question here. I have an MVC application calling Web API. One of the methods returns 405 error, and I have no idea why, especially that all of the others methods in the same controller work absolutely fine.
This is how I call this method from MVC end:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format("{0}/api/Account/ArchiveAddress?addressId={1}", uri, addressId));
request.Method = "Get";
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
}
catch (Exception e)
{
return RedirectToAction("Error", "Error", new { error = e.Message });
}
Where uri is a string:
http://localhost:52599
and addressId is an int
My method on the Web API end looks like this:
[Route("ArchiveAddress")]
public IHttpActionResult ArchiveUserAddress(int addressId)
{
var address = _addressRepo.Find(addressId);
...
As I said, I call many different methods on the API in the exact same way, and they all work fine. Just this one does not want to behave. What might be causing that?
I think you need to decorate your action method (ArchiveUserAddress) with the [HttpGet] attribute or name it something that begins with Get..., e.g. GetArchiveUserAddress. As it stands, it would do match the POST method which means there's no getter hence the error you're getting.
i am using the following code to athenticate the user using ServiceStack basic auth provider in my asp.net application and receiving serilization exception.Please answer if anyone has solve this problem.Thank you.
I am using the following code in my asp.net application:
<asp:Button ID="btnAuth" runat="server" OnClick="btnAuth_Click" Text="Authenticate"/>
I am recieving exception on clien.Post method in code behind file.
protected void btnAuth_Click(object sender, EventArgs e)
{
try
{
var baseUrl = Request.Url.GetLeftPart(UriPartial.Authority) + "/api";
var client = new JsonServiceClient(baseUrl);
var authResponse = client.Post<AuthResponse>(new Auth { UserName = "admin", Password = "12345" });
if (authResponse.ResponseStatus.ErrorCode == null)
{
//Do Something here
}
}
catch (WebServiceException ex)
{
throw ex;
}
}
Followin is Exeception Detail which i am recieving on clien.Post method:
[SerializationException: Type definitions should start with a '{', expecting serialized type 'AuthResponse', got string starting with:
Serialization exception that reads "expecting serialized type 'X', got string starting with:" means that the serializer tries to create an object from an empty string instead of a proper json-formatted string ("{Class:{Property:{Sub:value}}}").
In this case, most likely cause is server at baseUrl returning no response (interpreted as empty string) to a POST request. Misconfigured URL or exception on server side, maybe?
When I get referrer url, IIS 7 throws an exception. My code like this:
var referrer = Request.UrlReferrer == null ? null : Request.UrlReferrer.AbsoluteUri;
Application throws an ArgumentException with error message,
"Value does not fall within the expected range."
There is no problem in IIS 6.
This exception occurs when the page is navigated with "Response.Redirect"
Application main page has an Response.Redirect method according to role of current user. User main page throws this exception.
How can get Referrer URL in IIS 7.
Thanks,
Ran into similar problem when I tried to access the request object from a System.Threading.Task launched in the request processing.
I'm using the task to reduce response time - in my case most of the processing can be performed after request is sent.
That is, I had something like:
public ActionResult SomeAction()
{
new System.Threading.Task(() => {
// here I used this.Request.UrlReferrer and got weird ArgumenException error
}).Start();
return someActionResultThatDoesntRequireProcessing;
}
I've extracted UrlReferrer (and other this.Request.stuff that I needed) in delayed processing) into a separate "closure" variable (I've chosen them to have the very basic types):
public ActionResult SomeAction()
{
var urlReferrerAbs = this.Request.UrlReferrer.AbsoluteUri;
var clientAddress = this.Request.UserHostAddress;
// save other stuff from the request object
new System.Threading.Task(() => {
// here I used urlReferrerAbs instead of this.Request.UrlReferrer and the error has gone!
}).Start();
return someActionResultThatDoesntRequireProcessing;
}
That worked for me.