How to catch exceptions in grails REST controllers - grails

If you use a controller to implement rest APIs, you want to deal with any exception thrown and return a generic or specific well formed REST response.
We can't use global error URL mapping method, as the application has a number of APIs and interfaces with different response requirements, and we also don't know which type of Grails' HTTP error codes will be thrown (e.g don't know if it will be a 400, 422, 500 etc). Also, if we used the error page mappings, we won't be able to put relevant data into the JSON response.
E.g. this will generate a GrailsRuntimeException:
class SomeController {
def payload = request.JSON
def someMethod() {
BigDecimal x = new BigDecimal(payload.notExists)
}
The problem is, it seems impossible to catch any error thrown.
E.g. neither this approach:
def handleRuntimeException(RuntimeException e) {
render("some JSON error message")
}
Nor this approach:
try {
:
}
catch (GrailsRuntimeException e) {
render("some JSON error message")
}
Works - it never catches the error.
Tried GroovyRuntimeException, Exception, MissingMethodException, Throwable etc.
The only solution we can think of is to not do any work in the controller, do everything in a service, where apparently we can catch errors.
This approach:
static mappings = {
"500"(controller: "error")
}
Is not want we need for several reasons:
We have several different APIs in different controllers which would require different response formats.
we also have UI controllers, which would want the default error system which shows the stack trace etc.
We want to handle the error in the controller where the exception happened, so we can clean up, or at least can log or return the stat which only the controller knows.
Have decided the only way is to move all code into services, and do nothing in the controller except pass the request, and render the resultant string. i.e. all parameter handling, especially number conversion, is done in the service.

It's ironic that the solution that you see as suboptimal that you're settling for is exactly what you should always do. This isn't PHP - don't put logic in Controllers (or GSPs).
Services are by default transactional, so they're a great place to put code that writes to the database since that should always happen in a transaction. They're also excellent for business logic whether it's transactional or not, and you can either annotate individual methods with #Transactional to partition the methods into ones that run in a transaction and ones that don't, or split the services into some that are fully transactional and some that aren't.
If you keep all of the HTTP-related code in the controllers, doing the data binding from params, and calling helper classes (services, domain classes, taglibs, etc.) you get a good separation of concerns, and if the service layer doesn't know anything about params, HttpServletRequest, HTTP sessions, etc. then it's easily reusable in other Grails apps and even in non-Grails apps. They'll also be easier to test, since there isn't so much inter-related code that needs to be mocked and otherwise made test-friendly.
Using this approach, the controllers basically become dumb routers, accepting requests, calling helpers to do the real work, and delegating page rendering or response writing, or redirecting or forwarding.

I am very late to answer this, but I think it might help people stumbling and searching for solution.
Here is one of my blogs explaining Custom exception handling in grails and error responses for RESTfull services
Hope this might help someone

I am using grails 3.2.4 and there is no issue as you have explained here. I have moved all business logics inside the service class and catching exceptions by parent controller trait. Here I am handling this exception in another ParentExceptionController trait which is implemented by classes where such exception is occurring from service class. Example:
UserService {
boolean create(Map params) {
throw new InvalidParameterException('some message')
}
UserController implements ParentExceptionController {
UserService userService
userService.create(params.userDetails)
}
trait ParentExceptionController {
Object handleInvalidParameterException(InvalidParameterExceoption exception) {
log.error 'log message'
respond([message: exception.message])
}
first and second both are working in my case.

Related

Overriding Grails uncaughtExceptionHandler

I am using Grails 2.3 to create a REST API, and I want a better way to handle rendering error responses as a JSON response. What is have currently is a package of exceptions that all have a toJSON method. So all my controller methods wrap everything in the same try/catch blocks and render any error responses the same way.
What I really want is to have an uncaught exception handler that does all this without having to wrap everything in try/catch. So if there's an uncaught exception, it'll automatically convert the exception into JSON, set the appropriate status code, and write and flush the response.
Given all that, here's the actual question:
So the first question is: is this a dumb idea?
Since Grails handles all the thread pooling, I think I would need to register my handler at the beginning of every api call. Should I do this in the beforeInterceptor closure of each controller?
Also, how would I be able to access the response object from my handler in order to be able to write the proper response?
Even if someone could point me to the relevant grails classes in the docs, that would be a big help. I searched and could not find the classes where grails does this to see if I can use their existing classes instead of writing my own.
http://grails.org/doc/latest/guide/theWebLayer.html#mappingToResponseCodes might help. In essence, mapped custom ErrorController could render uncaught exceptions to JSON,
class MyJSONErrorController {
def handleError() {
def exception = request.exception
// perform desired processing to handle the exception
render exception as JSON
}
}
Doing beforeInterceptor or try catch block in each controller seems overwhelming. As Spring framework advocated, only catch exceptions that you need handle specifically than common errors.

ASP.NET MVC, throw HttpException vs return HttpStatusCodeResult?

I am developing a RESTful service and I want to return 400 for all unsupported URLs.
My question is when should I choose method 1 over method 2 and vice-versa..
//method 1
public ActionResult Index()
{
//The url is unsupported
throw new HttpException(400, "Bad Request");
}
This one seems to be better?
//method 2
public ActionResult Index()
{
//The url is unsupported
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Bad Request");
}
The second seems better as it doesn't involve exception throwing which comes at a micro-cost compared to the first example.
Being in a DevOps team, we are all in the mind-set where throwing more hardware at something to get a slightly better result is always a good cause. So I'm intentionally ignoring the micro-cost of firing a .NET exception.
If you're leveraging a telemetry framework like ApplicationInsights then just returning the status code gives you nothing more than a "failed request". It doesn't give you any useful information that allows you to either compile or get any information on the "why" of the failed request.
Telemetry platforms expect and want you to throw, because error telemetry is usually around .NET exceptions, so if you're not throwing you're creating a problem for operations.
I actually landed here, because I'm in the process of writing a Roslyn analyser and CodeFix for a project where folks love to write try{} catch { return BadRequest("put_the_reason_here"); } and neither DevOps or the Dev teams see nothing useful in the system telemetry in ApplicationInsights.
In my view you need to consider first if a request is made to the unsupported URLs. Then do you think of it is an exceptional situation or you expect that to happen? If you think of it as an exceptional situation then create and throw an exception (option 1). If you are expecting that you will receive many requests on the unsupported URL then treat it as a function of your application and use method 2.
That's said you will need to think about your clients' again if you are expecting too many requests on the unsupported URLs. In general I would prefer to throw an exception as I don't expect to receive too many requests on the unsupported URLs, and if it does happen then I would like to log it as an exception and investigate the reason.
Although this question is a bit old I figured I'd give my input since I came across this.
Errors are values. This goes for an HttpException (when unthrown) as well as an HttpStatusCodeResult. Thrown exceptions, however, create new code paths that are hidden away from your coworkers that may be one execution context higher up than yours and have to be given documentation that these code paths will be passed to them without notice. Values, however, tell you everything you need to know through their type. You can use their type in the expected execution path to tell whether an error has occured as well as find associated information with that error and log it.
I sometimes use (lightly extended) Exception's without throwing them to the next execution context to extract the useful debug information that David Rodriguez mentioned. There's never an excuse to be handing thrown exceptions to execution contexts above you that aren't actually exceptional, and this only really applies to things that are actually outside of your code's ability to handle (StackOverflowException, other fatal system exceptions, etc).
In a networked application, such as whatever MVC service you're running, the performance penalty from throwing exceptions is meaningless. The semantics and effects on maintainability, are not.
Network errors are values, and you should handle them like so.
you would throw an exception in code locations that cannot return an actionResult, such as in a controller constructor.

Localizing validation messages from Domain Objects (Entities)

It's not my intent to engage in a debate over validation in DDD, where the code belongs, etc. but to focus on one possible approach and how to address localization issues. I have the following behavior (method) on one of my domain objects (entities) which exemplifies the scenario:
public void ClockIn()
{
if (WasTerminated)
{
throw new InvalidOperationException("Cannot clock-in a terminated employee.");
}
ClockedInAt = DateTime.Now;
:
}
As you can see, when the ClockIn method is called, the method checks the state of the object to ensure that the Employee has not been terminated. If the Employee was terminated, we throw an exception consistent with the "don't let your entities enter an invalid state" approach.
My problem is that I need to localize the exception message. This is typically done (in this application) using an application service (ILocalizationService) that is imported using MEF in classes that require access to its methods. However, as with any DI framework, dependencies are only injected/imported if the object was instantiated by the container. This is typically not the case with DDD.
Furthermore, everything I've learned about DDD says that our domain objects should not have dependencies and those concerns should be handled external from the domain object. If that is the case, how can I go about localizing messages such as the one shown above?
This is not a novel requirement as a great many business applications require globalization/localization. I'd appreciate some recommendations how to make this work and still be consistent with the goals of a DDD.
UPDATE
I failed to originally point out that our localization is all database driven, so we do have a Localization Service (via the injectable ILocalizationService interface). Therefore, using the static Resources class Visual Studio provides as part of the project is NOT a viable option.
ANOTHER UPDATE
Perhaps it would move the discussion along to state that the app is a RESTful service app. Therefore, the client could be a simple web browser. As such, I cannot code with any expectation that the caller can perform any kind of localization, code mapping, etc. When an exception occurs (and in this approach, attempting to put the domain object into an invalid state is an exception), an exception is thrown and the appropriate HTTP status code returned along with the exception message which should be localized to the caller's culture (Accept-Language).
Not sure how helpful this response is to you, but localization is really a front-end concern. Localizing exceptions messages as per your example is not common practice, as end users shouldn't see technical details such as those described in exception messages (and whoever will be troubleshooting your exceptions probably has a sufficient level English even if it is not their native language).
Of course if necessary you can always handle exceptions and present a localized, user-friendly message to your users in your front-end. But keeping it as a font-end concern should simplify your architecture.
As Clafou said, you shouldn't use exceptions for passing messages to the UI in any way.
If you still insist in doing this, one option is to throw an error code instead of the message
throw new InvalidOperationException("ERROR_TERMINATED_EMPLOYEE_CLOCKIN");
and then, when it happens, do whatever you need to do with the exception (log, look up localization, whatever).
If localisation is important part of the domain/application you should make it a first class citizen and inject wherever it belongs. I am not sure what you mean with "DDD says that our domain objects should not have dependencies" - please explain.
You are correct for trying to avoid adding internal dependencies to your domain model objects.
A better solution would be to handle the action inside of a service method such as:
public class EmployeeServiceImpl implements EmployeeService {
public void ClockEmployeeIn(Employee employee) throws InvalidOperationException {
if (employee.isTerminated()) {
// Localize using a resource lookup code..
throw new InvalidOperationException("Error_Clockin_Employee_Terminated");
}
employee.setClockedInAt(DateTime.Now);
}
}
You can then inject the service using your DI framework at the point where you will be making the clockin call and use the service to insulate your domain objects from changes to business logic.

OpenRasta: Uri seems to be irrelevant for handler selection

When registering two handlers for the same type, but with different URIs, the handler selection algorithm doesn't seem to check the uri when it determines which handler to use.
If you run the program below, you'll notice that only HandlerOne will be invoked (twice). It does not matter if I call for "/one" or "/two", the latter supposed to be handled by HandlerTwo.
Am I doing something wrong or is this something to be fixed in OpenRasta? (I'm using 2.0.3.0 btw)
class Program
{
static void Main(string[] args)
{
using (InMemoryHost host = new InMemoryHost(new Configuration()))
{
host.ProcessRequest(new InMemoryRequest
{
HttpMethod = "GET",
Uri = new Uri("http://x/one")
});
host.ProcessRequest(new InMemoryRequest
{
HttpMethod = "GET",
Uri = new Uri("http://x/two")
});
}
}
}
class Configuration : IConfigurationSource
{
public void Configure()
{
using (OpenRastaConfiguration.Manual)
{
ResourceSpace.Has.ResourcesOfType(typeof(object))
.AtUri("/one").HandledBy(typeof(HandlerOne));
ResourceSpace.Has.ResourcesOfType(typeof(object))
.AtUri("/two").HandledBy(typeof(HandlerTwo));
}
}
}
class HandlerOne
{
public object Get() { return "returned from HandlerOne.Get"; }
}
class HandlerTwo
{
public object Get() { return "returned from HandlerTwo.Get"; }
}
Update
I have a feeling that I could accomplish what I want similar using UriNameHandlerMethodSelector as described on http://trac.caffeine-it.com/openrasta/wiki/Doc/Handlers/MethodSelection, but then I'd have to annotate each handler methods and also do AtUri().Named(), which looks like boilerplate to me and I'd like to avoid that. Isn't AtUri(X).HandledBy(Y) making the connection between X and Y clear?
Eugene,
You should never have multiple registrations like that on the same resource type, and you probably never need to have ResourcesOfType<object> ever associated with URIs, that'll completely screw with the resolution algorithms used in OpenRasta.
If you're mapping two different things, create two resource classes. Handlers and URIs are only associate by resource class, and if you fail at designing your resources OpenRasta will not be able to match the two, and this is by design.
If you want to persist down that route, and I really don't think you should, then you can register various URIs to have a name, and hint on each of your methods that the name ought to be handled using HttpOperation(ForUriName=blah). That piece of functionality is only there for those very, very rare scenarios where you do need to opt-out of the automatic method resolution.
Finally, as OpenRasta is a compsable framework, you shouldnt have to go and hack around existing classes, you ought to plug yourself into the framework to ensure you override the components you don't want and replace them by things you code yourself. In this case, you could simply write a contributor that replaces the handler selection with your own moel if you don't like the defaults and want an MVC-style selection system. Alternatively, if you want certain methods to be selected rather than others, you can remove the existing operation selectors and replace them (or complement them with) your own. That way you will rely on published APIs to extend OpenRasta and your code won't be broken in the future. I can't give that guarantee if you forked and hacked existing code.
As Seb explained, when you register multiple handlers with the same resource type OpenRasta treats the handlers as one large concatenated class. It therefore guesses (best way to describe it) which potential GET (or other HTTP verb) method to execute, which ever it thinks is most appropriate. This isn't going to be acceptable from the developers prospective and must be resolved.
I have in my use of OpenRasta needed to be able to register the same resource type with multiple handlers. When retrieving data from a well normalised relational database you are bound to get the same type response from multiple requests. This happens when creating multiple queries (in Linq) to retrieve data from either side of the one-to-many relation, which of course is important to the whole structure of the database.
Taking advice from Seb, and hoping I've implemented his suggestion correctly, I have taken the database model class, and built a derived class from it in a resources namespace for each instance of when a duplicating resource type might have been introduced.
ResourceSpace.Has.ResourcesOfType<IList<Client>>()
.AtUri("/clients").And
.AtUri("/client/{clientid}").HandledBy<ClientsHandler>().AsJsonDataContract();
ResourceSpace.Has.ResourcesOfType<IList<AgencyClient>>()
.AtUri("/agencyclients").And
.AtUri("/agencyclients/{agencyid}").HandledBy<AgencyClientsHandler>().AsJsonDataContract();
Client is my Model class which I have then derived AgencyClient from.
namespace ProductName.Resources
{
public class AgencyClient: Client { }
}
You don't even need to cast the base class received from your Linq-SQL data access layer into your derived class. The Linq cast method isn't intended for that kind of thing anyway, and although this code will compile it is WRONG and you will receive a runtime exception 'LINQ to Entities only supports casting Entity Data Model primitive types.'
Context.Set<Client>().Cast<AgencyClient>().ToList(); //will receive a runtime error
More conventional casts like (AgencyClient) won't work as conversion to a SubClass isn't easily possible in C#. Convert base class to derived class
Using the AS operator will again compile and will even run, but will give a null value in the returned lists and therefore won't retrieve the data intended.
Context.Set<Client>().ToList() as IEnumerable<AgencyClient>; //will compile and run but will return null
I still don't understand how OpenRasta handles the differing return class from the handler to the ResourceType but it does, so let's take advantage of it. Perhaps Seb might be able to elaborate?
OpenRasta therefore treats these classes separately and the right handler methods are executed for the URIs.
I patched OpenRasta to make it work. These are the files I touched:
OpenRasta/Configuration/MetaModel/Handlers/HandlerMetaModelHandler.cs
OpenRasta/Handlers/HandlerRepository.cs
OpenRasta/Handlers/IHandlerRepository.cs
OpenRasta/Pipeline/Contributors/HandlerResolverContributor.cs
The main change is that now the handler repository gets the registered URIs in the initializing call to AddResourceHandler, so when GetHandlerTypesFor is called later on during handler selection, it can also check the URI. Interface-wise, I changed this:
public interface IHandlerRepository
{
void AddResourceHandler(object resourceKey, IType handlerType);
IEnumerable<IType> GetHandlerTypesFor(object resourceKey);
to that:
public interface IHandlerRepository
{
void AddResourceHandler(object resourceKey, IList<UriModel> resourceUris, IType handlerType);
IEnumerable<IType> GetHandlerTypesFor(object resourceKey, UriRegistration selectedResource);
I'll omit the implementation for brevity.
This change also means that OpenRasta won't waste time on further checking of handlers (their method signatures etc.) that are not relevant to the request at hand.
I'd still like to get other opinions on this issue, if possible. Maybe I just missed something.

How do I implement error-handling in Grails?

I am just starting out with Grails, obviously. I've created my domain class and controller, added my own logic to the controller, and everything is working properly -- as long as nothing goes wrong.
My custom controller action looks like this:
def create = {
try
{
// Get the parameters.
def uid=params["uid"]
def pwd=params["pwd"]
if (!uid || !pwd)
{
throw new Exception('User ID and password are required')
}
/* other code */
}
catch (Exception ex)
{
println ex.getMessage()
}
}
My code (/* other code */) is working fine. When the exception is thrown, however, the error message is printed to the console and the browser throws a 404 error. Obviously, this isn't the way to go.
What's the correct way to do this?
TIA,
John
Based on the code snippet you provided, I guess what you really want is validation of some sort of user input (probably a form). If this is the case, throwing exceptions definitely isn't the way to go. You should only throw an exception if something exceptional (something unexpected, that usually shouldn't happen during normal operation) happens - by the way, this also holds for other programming languages.
Grails provides very good support for validating user inputs. Depending on the context, you should either define constraints in your domain classes, or use command objects and define constraints there (if the fields to be validated are not backed directly by a domain class). This way Grails validates the user input automatically against your constraints (there are many different kinds, such as size, blank/non-blank, or even RegExp constraints) and stores the errors and the corresponding messages in the domain class. You can then easily display the appropriate localized error messages in your form (view). It's good practice to display the errors right next to the input field they refer to.
Have a look at the Reference Documentation - especially chapter 7 (validation).
The 404 you are getting is probably not due to the (caught) exception, but rather because you don't have a view called create.gsp or a render/redirect call in your action.
I hope this answers your question or at least points you in the right direction. Good luck!
As Daniel says, use constraints in your domain class instead and use the validate() method in your controller instead of throwing exceptions.
If validate() returns false, render the form again with an error message.
In your BootStrap.groovy file you can do this set up catch-all handlers for different Java Exceptions. Here is an article about it.

Resources