Transactional service causing ErrorController to Render instead of desired view - grails

I've inherited a grails project in which an Error Controller is used.
Within the URLMappings there is the following entry:
"500"(controller: 'error', action:'error')
The specific errorController renders a specific view:
render view:'/error/prodError'
What I don't understand is how to bypass error controller for 500 errors and send to view /play/play but without removing the old one for other situations.
Even though I catch exceptions from the playService, I still get /error/prodError instead of /play/play.
I've debugged the code and seen that the render method is called twice. It is called once to go to /play/play but another time for /error/prodError when an exception is thrown in the service and the transaction is rolled back.
See playController excerpt below:
PlayController
try{
playService.play(parame:params} //Runtime exception thrown from playService.
//play is transactional
}
catch(Throwable t){
//Why isn't /play/play rendered?
//How do I pass errors to playservice for alert rendering?
render view: '/play/play',
model: [
domain: domain,
customer: customer,
game: game]
return
}
Update
Specifically, the errorController is entered because of an UnexpectedRollbackException that is the result of the rollback.
SO: How would someone go about not entering the ErrorController for a specific type of Exception that results from a specific Controller?

If you don't want to handle the error within a controller, you could render your (or any other) view with the following url mapping:
"500"(view:'/play/play')
If you need to handle individual exception you do it like this:
static mappings = {
.
.
.
"500"(controller: "error", action: "unexpectedRollback", exception: UnexpectedRollbackException)
"500"(controller: "errors", action: "nullPointer", exception: NullPointerException)
.
.
"500"(controller: 'error', action:'error')
}
As mentioned in docs you should avoid throwning exceptions from your error controller due to StackOverflowExceptions. I think it's not possible to divide between two exceptions of the same type but thrown from diffent controller.
If you handle the exception within your error controller you could try to set the response code directly. So - the url mapping may not handle your already handled exception.

Related

An unhandled exception occurred while processing the request in mvc

the topic error showing me when I am redirect the view page from controller.
Here is the full error
An unhandled exception occurred while processing the request.
InvalidOperationException: The view '~/Views/Udhyog/Services.cshtml' was not found. The following locations were searched:
~/Views/Udhyog/Services.cshtml
Here is my controller code
public virtual IActionResult Index()
{
return View("~/Views/Udhyog/Services.cshtml");
}
I am surprised that why this type of error is showing, because In views => Udhyog named one folder and in that I want to show the services.cshtml view page.
So, is there my code wrong or is there any another method to redirect the view page?
return View("../UdhyogMaster/Services");

MVC Error Handling with WCF Service

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

How to implement global back end exception handler

I have grails application.
I want to implement global grails back end exception handler.
Means if there are any exception in application at back end like NullPointer, ArrayIndexOutOfBounds or any other exception is raised then some code should be executed. How we can do this in grails 2.4.4.
You can hadle it using UrlMappings.
From the documentation
static mappings = {
"403"(view: "/errors/forbidden")
"404"(view: "/errors/notFound")
"500"(controller: "errors", action: "illegalArgument",
exception: IllegalArgumentException)
"500"(controller: "errors", action: "nullPointer",
exception: NullPointerException)
"500"(controller: "errors", action: "customException",
exception: MyException)
"500"(view: "/errors/serverError")
}
With this configuration, an IllegalArgumentException will be handled by the illegalArgument action in ErrorsController, a NullPointerException will be handled by the nullPointer action, and a MyException will be handled by the customException action. Other exceptions will be handled by the catch-all rule and use the /errors/serverError view.
Use Grails declarative exception handling for controllers
def handleLException(Exception e) {
render "Opps: ${e.message}"
}
More information here: http://docs.grails.org/2.4.5/guide/single.html#controllerExceptionHandling

How to handle grails exceptions in an ajax request?

If I am making a regular request I can define handling of errors and exceptions in UrlMappings.groovy as in the following example:
"403"(controller: 'error', action: 'index', params:['code':'403'])
"404"(controller: 'error', action: 'index', params:['code':'404'])
"500"(controller: 'error', action: 'index', params:['code':'500'])
"500"(controller: 'home', action: 'noPrivileges', exception: IllegalOperationException)
I can then handle the errors in a specific controller and render a view of my choice e.g.
class ErrorController {
def index = {
render view: "/errors/myErrorPage", model: [code: params.code]
}
}
This works perfectly and whenever there is an error on server I get my error page.
Now how can I achieve the very same behavior for ajax requests? I am making ajax requests either with grails remoteFunction or formRemote. Everytime when an exception occurs on the server, I want to execute the same piece of code in javascript (e.g. I want to show an alert with alert('There was an exception')).
The above described approach does not work for ajax requests. I still get back an error and even though there is content of myErrorPage.gsp in the error, it is not printed into the html element which I specified with update parameter of formRemote or remoteFunction.
I finally found a perfectly clean solution compatible with the approach which is used for handling standard requests.
You need to modify action which is handling the error as in the following example:
class ErrorController {
def index = {
if (request.xhr) {
response.status = 200
render template: "/errors/myAjaxErrorTemplate", model: [code: params.code]
} else {
render view: "/errors/myErrorPage", model: [code: params.code]
}
}
}
With request.xhr you can differentiate between ajax request and a standard request. In ajax request you further need to tell grails that the response is OK with setting response status to 200.
Very nice and clean. :) I am surprised this can't be googled anywhere...
The remoteFunction trigger a couple of events onFailure and on_ERROR_CODE. You can use that events to show your warning messages.
You can see more details in docs
If the request status is set correctly you could define an JavaScript function via the onFailure attribute of remoteFunction/formRemote.
Within this function you could handle your exception on client side.
Using the sample from the docs it could look like this:
<select onchange="${remoteFunction(action: 'bookByName',
update: [success: 'great', failure: 'ohno'],
params: '\'bookName=\' + this.value'),
onFailure: 'handleError'}">
<option>first</option>
<option>second</option>
</select>

MVC Application FaultException Thrown How to get to display Error page

I have mvc 3 application which when a Standard generic throw new Exception is thrown in code the error page from Views\Shared\error.cshtml is shown. This is done by simply setting <customErrors mode="On"/>. (This is As expected and as Desired)
The application is using WCF services in middle tier which when these services generate FaultException MVC is not showing up the error page it is showing details of the web service call to the user on screen. All I want to do is handle the error in my code and show the user the Error.cshtml. I have tried changing global asax but this dosent work.
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
if (exception.GetType() == typeof(FaultException))
{
throw new Exception("There was a fault exception that i do not want to show details of to user.");
}
}
Try creating an ErrorController as asp.net MVC will try to resolve the link you specified in the web.config as {Controller}/{View} unless you specify it to ignore that page. Also, you may want to apply an attribute to handle exceptions instead.
You can also create a error controller/view and in your catch block redirect to the custom error page of your choosing
try
{
foo.bar()
}
catch(SpecificException)
{
RedirectToAction("500", "Error");
}

Resources