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.
Related
After my research, my own answer to my question is: unfortunately, no. But I'd like to hear your opinion as well.
I have 4 controllers each having 5 methods. Every method has a try-catch block. In case of an exception, I want to log on a file a message with all the parameters of that controllers. So I have to write the basically same log instruction 4x5=20 times. If I want to change the logging message, I have to do it 20 times. On one hand, sounds like a hard to maintain problem. But on the other hand, every controller has its own signature.
Would it be possible to have some base/parent/God method that virtually logs for every controller? And of course if I will be needing to adapt/override the logging instruction just for one controller this should be also possible. Is there any technique?
How about if I just need to generate for every controller methods a GUID?
There are many ways to achieve a single piece of code that can log all your controller methods. The easiest implementation which comes to my mind is to just write a method that takes an action or function. Then inside just call that action/function and wrap it in any logging that you wish to use. Like so:
public void ExecuteWithLogging(Action actionToExecute)
{
try
{
action() // the same as action.Invoke()
}
catch(Exception e)
{
// code your logging here
}
}
then inside your controller's methods you could use it like this:
ExecuteWithLogging(() =>
{
// your controller code
});
But there are other ways. You could probably use attributes to mark each method as logged. Or maybe you could write some middle-ware that just logs everything (like maybe in this article -> https://exceptionnotfound.net/using-middleware-to-log-requests-and-responses-in-asp-net-core/).
The options are many!
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.
In Grails there is a message.properties file. In this file message are defined like this:
exampleClass.fieldOne.label=Field One
otherExampleClass.fieldOne.label=Field One
I want the ability to use both messages even though they are textually the same. I would like to define them like this:
exampleClass.fieldOne.label=Field One
otherExampleClass.fieldOne.label=${message(code: 'exampleClass.fieldOne.label')}
... but that just make a a call to otherExampleClass.fieldOne.label return the string ${message(code: 'exampleClass.fieldOne.label')} instead of the desired string Field One.
In the message.properties I think that you cannot do it, but maybe with a convention and modifying the templates of the Grails you can achieve it. So my idea is:
Define a convention for your messages (for example, initialize the message with some special char)
exempleClass.fieldOne.label=FieldOne
otherExampleClass.fieldOne.label=#exempleClass.fieldOne.label
Create a TagLib to handle the message
class MyTagLib {
static namespace = "my"
def inheritedMessage = { attrs, body ->
String message = g.message(attrs)
if(message.startsWith("#")) {
//get the other message...
}
out << message
}
}
And finally install templates and change the <g:message/> for <my:inheritedMessage/> or whatever you call it.
For step 2, another approach is to override g.message(), with the benefit of not need the step 3 and make available for all parts of your app the modification. The con is that it will have to be good documented and disseminated or can cause some confusion in other devs.
EDIT
To cover all messages I think the better approach is to customize the messageResource used by Grails. Here is a question that covers how to do it with Spring, to get the messages from the database, could be a start point. And here is a question that shows how to replace the bean in Grails.
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.
Could anyone please guide me on what's the best practice to handle exception in ASP.NET MVC?
Controller?
Model?
Model (Contains EF logics i.e. save, update etc) throw any exception and catch in Controller?
In any method or block of code where you may expect specific exceptions (interacting with a database or an external service which may or may not not be available, etc.) wrap that code in a Try/Catch to catch the specific exception(s) in question. You'd want to know exactly what kind of exceptions occurred to handle them properly. (Naturally, use a Finally block to dispose of any open resources.) How to properly handle them is up to you and how you want your application to behave.
You should definitely have a global exception handling to catch anything unexpected which falls through the cracks. At no point should an unhandled exception bubble up to the user. The global exception handler should just present the user with a friendly error message and should log the exception and notify you of what happened. Generally, a good goal is to identify the exception and add error handling code to catch it in its localized state before it bubbles up to global. The goal, over time, should be to have as few global exceptions as possible and to have any potentially-exception-generating code have its own error handling to guard against those cases.
An example of the latter could be something as simple as a particular method receiving null arguments that you want to check for before using those arguments. One thing you want to avoid, however, is using exception handling for logic flow. For example...
Let's say you have a method which takes a custom object as an argument:
public MyMethod(MyObject obj)
{
// ...
}
Your original code assumes that obj will always have a value. However, after some time of production use, you discover that obj is sometimes null and that it's throwing a NullReferenceException from within that method, which is being caught by the global exception handler.
You may be tempted to just wrap the code in MyMethod in its own Try/Catch block to catch that exception. This isn't necessarily a good idea (though there may be cases where it is). Instead, you'd want to check for null at the start of the method:
public MyMethod(MyObject obj)
{
if (obj == null) throw new ArgumentNullException("obj can not be NULL");
// ...
}
This encapsulates the method better and allows it to throw controlled exceptions. Exceptions aren't bad things, only unexpected exceptions. Note that the above will still throw the exception which will still bubble up to the global handler. Thus, it's also a good idea to wrap the calls to this method in a Try/Catch block in order to catch the ArgumentNullException and handle it accordingly. Perhaps the code which calls this method can fix the null reference and try again, perhaps it can try something else, etc. You still don't want it to bubble up to the global handler if possible, since this has become an "expected" exception and can be handled accordingly.
Naturally, you still want to avoid the throwing/catching of the expected exceptions in the above example, so similar checks for null should happen before calling the method so that the method isn't even called.
Maybe if the object is null you can directly present the user with an error message and log the error and notify you of as much information about the state of things as possible so that you can research why it's null and fix it. Maybe being null is a perfectly acceptable state of that object at that time according to the logic of the application. If so, check if it's null and don't bother calling the method. Just carry on as normal.
It's a lot of error-checking and handling code, but that's a good thing.
Edit: Another thing to note about exception handling is that you should catch the exception only if you can actually handle it at that time. If the method can't handle it internally, let the exception bubble up from the method to the calling method, and so on. Thus, the only exceptions which should reach the global handler are exceptions which you can't actually handle anywhere in the code (which is why it's a good goal to fix and prevent global exceptions).
"Handle" in this case would mean being able to actually do something about it. Maybe that something is to just log it and carry on, maybe that something is to perform some specific logic, etc. But to catch, log, and re-throw is bad design. If you can't recover from the exception, let it bubble up.
The best way is to catch the exception globally, log it using Elmah. Otherwise you will have to put all your exceptions in your every controller code and that would be a lot of repetition especially for CRUD operations