I was trying out the ToDo sample and ran into an unhandled Excaption while trying out the Concurrency Handling.
The dataservice.js contains these lines in saveFailed(error) method:
if (detail && detail.ExceptionType.indexOf('OptimisticConcurrencyException') !== -1) {
// Concurrency error
reason =
"Another user, perhaps the server, may have deleted one or all of the todos.";
manager.rejectChanges(); // DEMO ONLY: discard all pending changes
}
The client never gets to this point due to an unhandled OptimisticConcurrencyException in:
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle) {
return _contextProvider.SaveChanges(saveBundle);
}
I was trying to catch this and return the Exception which was kind of stupid as the Exception is not of type SaveResult. Is this a bug or am i missing an configuration somewhere?
Greets
Any server side errors should be returned to the promise.fail handler. i.e.
em.saveChanges().then(function(saveResult) {
// normal path
}).fail(function(error) {
// your concurrency exception message will be part of the error object.
});
Error on my side here... Clicking 'Continue' on the Exception Windows in VS the javascript handler is executed.
Related
I saw similar post Error Handling with WCF Service and Client Application to my question but I needed more help.
I have a MVC project with the WCF Service. I understand that WCF needs to throw a FaultException. But my question is what is the best way to show the error message created by an error in WCF. I just want to redirect all the errors (possibly all FaultException) to one error page (will be generic) but message will be different.
I also would like to use [HandleError] attribute so that I don't have to implement catching FaultException for all the methods calling the WCF service.
As you know how you can handle WCF exceptions but in my opinion this is better to observe these:
1-This not good idea to show user exactly exception message, this is better to show very understandable message for example "Operation get failed there is may problem with back-end service, try again or notify admin"
2- It's is boring end user to redirect to public error page.
3- This is better show the public prompt to user which tell user that the operation get failed exactly where the user do action not redirect it to another page.
4- At the end If you want to do what you want try these:
try
{
//Call your wcf
}
catch(Exception exp)
{
//Logging.Log(LoggingMode.Error, "You message , EXP:{0}...", exp.ToString());
Response.Redirect("~/ErrorPages/Oops.aspx?Error=WCfOperationFailed", false);
}
in your error page page_load:
switch (Request.QueryString["Error"].ToString())
{
case "WCfOperationFailed":
litError.Text = string.Format("<h2>Error!.</h2><br/><p>{0}.</p>",GetError());
break;
default:
break;
}
public string GetError()
{
Exception lastError = Server.GetLastError();
return lastError.ToString();
}
or you can redirect error message as a QueryString to error page and show it to user in Page_load like:
//in catch block
Response.Redirect("~/ErrorPages/Oops.aspx?Error="+exp.Message, false);
in error page Page_load :
txtError.Text = Request.QueryString["Error"].ToString();
However, you can trap errors that occur anywhere in your application by adding code to the Application_Error handler in the Global.asax file:
void Application_Error(object sender, EventArgs e)
{
Exception exc = Server.GetLastError();
if (exc is HttpUnhandledException)
{
// Pass the error on to the error page.
Server.Transfer("ErrorPage.aspx?Error="+exc.Message, true);
}
}
This link can be helpful there are some examples
Error Handling
The error object that is returned from breeze manager saveChanges() don't have the array entitiesWithErrors, but instead has the entityErrors array (perhaps is as it is on breeze.js version: 1.4.12, metadataVersion: 1.0.5)
The returned error object looks like...
Error {stack: "Error: Client side validation errors encountered", entityErrors: Array[6], message: "Client side validation errors encountered see the Errors collection on this object for more detail" entityErrors: Array[6] bla. bla..
Thus the code bellow will fail and I will need to refactor it if I am not able to work with entitiesWithErrors
function getErrorMessages(error) {
function getValidationMessages(err) {
try {
return err.entitiesWithErrors.map(function (entity) {
return entity.entityAspect.getValidationErrors().map(function (valError) {
return valError.errorMessage;
}).join('; <br/>');
}).join('; <br/>');
} catch (e) {
}
return 'validation error';
}
var msg = error.message;
if (msg.match(/validation error/i)) {
return getValidationMessages(error);
}
return msg;
}
This breaking change was made in Breeze version 1.4.0. From the release notes,
The description of client side validation errors caught during a save
before posting to the server has changed.
Client side validation errors caught during a save, but before posting
to the server, cause the save to fail and be routed to the fail
promise. The fail promise returns an error object that contains a
description of the errors. This description has changed.
Previously this error object contained an entitiesWithErrors property
that contained a list of all of the entities that had failed
validation. This property has now been replaced with the entityErrors
property. The entityErrors property returns a collection of
entityError objects as described above.
This change was made in order to retain consistency between save
failures that occurred on the server and those that failed before
posting to the server on the client.
To refactor your code, you simply do,
return error.entityErrors.map(function (entityError) {
return entityError.errorMessage;
})
Hello I am new in mvc so I have a problem during the DB update. I have table in database which column is defined as a unique key that means I don't want to same data in that column but at the time of entering same data my data access layer class generates an exception called DbUpdate exception. I just want to handle this exception by sending a message "Your given data is already exists".. Please help me. Thanx in advance.
Generally, the idea is you want to raise a custom exception which make sense to each layer. The reason for this is because you want to keep your DAL abstract, for example, in your DAL you would catch this particular exception (DbUpdateException) and raise your own custom exception e.g.
try
{
...
myContext.SaveChanges();
}
catch (DbUpdateException ex)
{
throw new DuplicateDataException("Data already exists");
}
Then in your business layer, if you want to further abstract you could throw a domain exception
try
{
dataStore.Save(new Entity { ... });
}
catch (DuplicateDataException ex)
{
throw new DomainException(ex.Message);
}
Then finally in your controller, pass the error to the view
[HttpPost]
public ActionResult SomeAction(SomeModel model)
{
try
{
myDomain.Save(model);
return View("Success", model);
}
catch (DomainException ex)
{
return View("Error", ex.Message);
}
}
The example is completely fictitious of course and may or may not apply to your specific code-base, however, the goal is to demonstrate how the exception will effectively "bubble-up" from your DAL layer back to your UI.
I am placing particular emphasis on using custom exceptions simply because it provides you with a nice clean abstraction.
I am initializing FluentNHibernate from Application_Start event like so:
Fluently.Configure()
.Database(OracleDataClientConfiguration.Oracle10
.Driver<NHibernate.Driver.OracleDataClientDriver>()
.ConnectionString("MyConnectionString")
.DefaultSchema("MySchema")
)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<SomeClass>())
.BuildConfiguration()
.BuildSessionFactory();
If the connection string is bad, or connection to the DB fails for some other reason, I get a TNS No listener exception. I would like to display/log this exception but Application_Start (and Applicaiton_Error) doesn't have an HttpContext or Response object in IIS7 Integrated mode. The user gets a yellow screen of death telling them to turn custom errors On. Elmah doesn't log the message either. I would like to solve the problem in one of two possible ways:
Disable nhibernate configuration from connecting to the database on configuration.
Provide custom user feedback based on the error and get Elmah working (somehow). This would be my ideal choice.
I was able to move NHibernate configuration to run on Session_Start, as described here, which gets exception handling working for this error, but then I get other exceptions that can be misleading to the root cause of the problem. Does anyone have a good solution for this scenario?
Thank you.
This is what I do:
void Application_Start() {
try {
// setup your app / nhibernate
} catch(Exception ex) {
Application["StartupError"] = ex
}
}
void Application_BeginRequest() {
var startupError = Application["StartupError"] as Exception;
if (startupError != null)
throw new Exception("Error starting application", startupError);
}
In your BeginRequest method you have access to the Request and can do what you want to show the error (or show a nice page)
i'm trying to send back a simple error message as Json, with the HTTP code as 404.
So i started out writing my own IExceptionFilter that checks to see the exception. To keep this simple, if the exception throw is of type ResourceNotFoundException then i set the code to 404. Otherwise everything else if 500.
Now, the problem is .. the default IIS7 404 error message is returned :( my code is called .. but it seems to bypass it (later on in the pipeline)...
is there some trick i need to do?
do I need a custom error handling (in the web config) to be turned on or something?
Edit:
I'm trying to do what twitter does. Their Http Response Code documentation shows / explains some examples how they handle 404's, etc.. and i'm wanting to do that in my MVC app.
Edit 2:
The code i've done is listed here, for anyones reference :)
When you are handling your exception, are you setting ExceptionHandled to true?
Here's a quick example...
HandleException(ActionExecutedContext filterContext)
{
Exception exception = filterContext.Exception;
//Check if our exception has been handled.
if (filterContext.ExceptionHandled == false)
{
//Do your exception stuff
filterContext.Result = YourExceptionMessageAsAnActionResult();
//Set it as null.
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
}
}