Exception handling with dynamic mixins in Grails controller - grails

I am using dynamic mixins on my Grails 2.3.11 controllers according to this proposal on SO, for DRY reasons:
class SomeApiController {
def SomeApiController() {
SomeApiController.mixin MyControllerMixin
}
...
Unfortunately it does not work for exception handlers, like:
class MyControllerMixin {
...
def businessException( BusinessException e ) {
log.error( "API exception: ${e.message} ${e.errorCode}", e )
def result = [
status: 'Failure',
errorCode: e.errorCode.name()
]
response.status = 400
render result as JSON
}
...
}
In this case, the default exception handler in SomeApiController is called when a BusinessException is thrown from somewhere. It works nicely if I place the handler directly in the controller, though, but this is what I want to avoid obviously.
Is there any workaround to get that working as well?

See http://grails.org/doc/latest/guide/theWebLayer.html#controllerExceptionHandling. That includes the following...
Exception handler methods must be present at compile time.
Specifically, exception handler methods which are runtime
metaprogrammed onto a controller class are not supported.

Related

Error occurred initializing command object on succeeding command objects in controller

I have the defined following controller
class BookController {
def book(BookCommand bookCommand,
AnotherBookCommand bookCommand2)
{
....
}
When I debugged it, binding is done on the bookCommand and when it's bookCommand2's turn for binding, it throws this exception
Error in object 'bookCommand2': codes []; arguments []; default message [Error occurred initializing command object [bookCommand2]. org.apache.groovy.json.internal.Exceptions$JsonInternalException: Wrapped Exception
CAUSE java.io.IOException :: Stream closed]
If I try to switch the order of the parameters i.e.
class BookController {
def book(AnotherBookCommand bookCommand2,
BookCommand bookCommand)
{
....
}
Binding is done on the bookCommand2 and binding of bookCommand throws the exception.
Error in object 'bookCommand': codes []; arguments []; default message [Error occurred initializing command object [bookCommand]. org.apache.groovy.json.internal.Exceptions$JsonInternalException: Wrapped Exception
CAUSE java.io.IOException :: Stream closed]
Any idea what's happening here?
We do not support binding the request of the body to multiple command objects. One option you have is to aggregate them into 1 class with something like this:
class SomeClass {
BookCommand bookCommand
BookCommand anotherBookCommand
}
Then have your controller action accept one of those and organize the body of the JSON accordingly.

Grails 2.4.3 - Asynchronous Programming #DelegateAsync

Suppose the following situation...
I have to perform a process which takes a lot of time (about 1 hour)
and I do not want the user of my application to wait until it ends.
The business logic of this process is encapsulated in several services.
So:
class MyService{
def myService2
def myService3
public doSomething(){
myService2.doSomething()
myService3.doSomething()
}
}
class MyController{
def myService
def anAction(){
myService.doSomething()
redirect(action:'index')
}
}
I want the call to my service to be asynchronous.
I tried to create an asynchronous service as indicated by the Grails documentation, using #DelegateAsync.
class AsyncMyService {
#DelegateAsync MyService myService
}
class MyController{
def asyncMyService
def anAction(){
asyncMyService.doSomething()
.onComplete { List results ->
println "completed!"
}
redirect(action:'index')
}
}
But I get the following error when compiling my application:
Caused by ConversionNotSupportedException: Failed to convert property value of type
'MyService2$$EnhancerBySpringCGLIB$$f08a1b38' to equired type 'grails.async.Promise'
for property 'myService2'; nested exception is java.lang.IllegalStateException: Cannot
convert value of type [MyService2$$EnhancerBySpringCGLIB$$f08a1b38] to required type
[grails.async.Promise] for property 'myService2': no matching editors or conversion
strategy found
Any ideas to solve this problem?
Thanks!

New action in Grails controller errors out

I'm new to groovy & grails so this may be silly.
But I have a very simple hello world app, the index action works fine, but I tried to add a new action ok and it errors out when rebuilding.
My controller is very simple
class AggregatorController {
def index() {
render "hello world 2222"
}
def ok() {
render "no"
}
}
This is the error I get:
org.grails.core.exceptions.GrailsRuntimeException: Error instantiated artefact class [class nba.AggregatorController] of type [class org.grails.core.DefaultGrailsControllerClass]: InvocationTargetException
And inside of the traceback I see this:
Caused by: java.lang.NoSuchMethodError: nba.AggregatorController.ok()Ljava/lang/Object;
If I delete the ok method everything works great

Why isn't my own Exception derived type recognised by Elmah?

I've just implemented Elmah for logging in my MVC3 app, and of course all is well, except that when I use signalling to log a custom exception, Elmah seems to 'see' the InnerException property of my custom exception, but not the custom exception itself.
When I use the code below to signal the exception, instead of seeing, "CtsDataException: Error" in my error log, as I would expect, I see, "DbEntityValidation: Validation failed for one or more entities.", the inner exception and its message. If I open the log item, I see that my custom exception has correctly been logged, so it looks like the 'exception descriptor' is wrong, not the actual log entry.
What am I doing wrong?
PS, my custom exception is as such:
public class CtsDataException: Exception
{
public CtsDataException(string message, Exception innerException): base(message, innerException)
{
ValidationResults = new List<CtsDbValidationResult>();
var vex = innerException as DbEntityValidationException;
if (vex != null)
{
ValidationResults = vex.EntityValidationErrors.Select(e => new CtsDbValidationResult(e)).ToList();
}
}
public IEnumerable<CtsDbValidationResult> ValidationResults { get; set; }
}
The signalling code looks like this:
protected void HandleDbEntityValidationException(DbEntityValidationException vex, string message)
{
var ctsEx = new CtsDataException(message, vex);
ErrorSignal.FromCurrentContext().Raise(ctsEx);
}
HandleDbEntityValidationException is on my base controller. It is invoked in derived controllers like this:
catch (DbEntityValidationException vx)
{
var msg = string.Format("Error updating employee '{0}'", entity.RefNum);
HandleDbEntityValidationException(vx, msg);
}
I've done some of my own testing and come to the conclusion that it's not ELMAH choosing to report only the InnerException. If you take a look at the details for the error and then click Original ASP.NET error page, you'll see that the original yellow screen that occurred will list the Exception Details as the InnerException and not the primary custom exception thrown. The stack trace further shows the original custom exception that was thrown instead. This is the information ELMAH is using in logging the error.
My testing consisted of creating a CustomException class that did nothing more than inherit from Exception. I then simply called:
throw new CustomException("error!", new NullReferenceException());
... and what got reported was the NullReferenceException with CustomException only appearing in the Stack Trace.
My theory of choice in this scenario is that ELMAH is choosing to display the exception that was thrown rather than the exceptions used to wrap it. If ELMAH had a way to include a message with the log, I think this "wrap in a more descriptive but ultimately irrelevant exception that is never thrown" malarkey could end.
I realize that I'm a few years late to actually answer the original question on time, but for others trying to achieve what I think was the OP's intention, I came across a bit of smartness in the LibLog package for Hangfire (slightly adapted):
var _errorType = Type.GetType("Elmah.Error, Elmah");
dynamic error = Activator.CreateInstance(_errorType, originalException);
error.Message = "Your custom message";
error.Type = "Error"; // Or type of original exception or ...
error.Time = DateTime.Now;
Elmah.ErrorLog.GetDefault(null).Log(error);

Grails common exception handling in grails 1.1

Some one please tell me how to handle RunTimeExceptions in grails version1.1 .I have followed the following tutorial.I could not get it working.
http://blog.bruary.net/2008/03/grails-custom-exception-handling.html
I have MyException which extends RunTimeException .If this particular exception comes I want show different error page.Is it possible to achieve in grails 1.1 version?
Can you provide some sample code, where some RuntimeException is thrown?
It is difficult to answer your question properly, if you don't tell what your exact problem is.
As far as I could tell your from this point, your BootStrap.groovy should look something like this:
class BootStrap {
def exceptionHandler
def init = { servletContext ->
exceptionHandler.exceptionMappings =
[ 'NoSuchFlowExecutionException' :'/my/doIt',
'java.lang.Exception' : '/error',
'org.you.YourCustomException' : '/yourErrorController/yourErrorAction' ]
}
def destroy = { }
On the other side, in your code, you have to catch occuring RuntimeExceptions and transate them into your custom exception.
And here we are at the interesting point: Why do you want to do this?
Wouldn't it be much more comfortable to redirect when RuntimeExceptions are thrown?

Resources