14

When getting an HTTP status code 500, I want to display 2 different pages according to the running environment.

In development mode, I want to display a stackStrace page (like the default Grails 500 error page) and in production mode, I want to display a formal "internal error" page.

Is it possible and how can I do that ?

pnuts
  • 58,317
  • 11
  • 87
  • 139
fabien7474
  • 16,300
  • 22
  • 96
  • 124

2 Answers2

20

You can do environment specific mappings within UrlMappings.groovy

grails.util.GrailsUtil to the rescue

Its not pretty, but I think it will solve your issue

E.g

import grails.util.GrailsUtil

class UrlMappings {
    static mappings = {


        if(GrailsUtil.getEnvironment() == "development") {

             "/$controller/$action?/$id?"{
                constraints {
                    // apply constraints here
                }
            }

            "/"(view:"/devIndex")
            "500"(view:'/error')
        }

        if(GrailsUtil.getEnvironment() == "test") {
            "/$controller/$action?/$id?"{
                constraints {
                    // apply constraints here
                }
            }

            "/"(view:"/testIndex")
            "500"(view:'/error')

        }



        if(GrailsUtil.getEnvironment() == "production") {
            "/$controller/$action?/$id?"{
                constraints {
                    // apply constraints here
                }
            }

            "/"(view:"/prodIndex")
            "500"(view:'/error')

        }
    }
}
tinny
  • 4,232
  • 7
  • 28
  • 38
  • Thx. I'll try it and update this thread. Is it not possible to have the if condition ONLY for "500" mapping? – fabien7474 May 27 '10 at 23:50
  • Yes. The above is just an example – tinny May 28 '10 at 02:28
  • Or you can also check the environment directly from GSP (like ) and adjust display accordingly. – pm_labs Mar 21 '12 at 01:02
  • 1
    You can just put this `"500"(view: environment == 'production' ? '/prodError' : '/error')` or maybe even this `"500"(view: "${environment}-error")`, both providing that `import static grails.util.GrailsUtil.environment` – jglatre Nov 21 '12 at 18:30
  • 4
    As `GrailsUtil.getEnvironment()` is depreciated better to use `Environment.getCurrent()` or simply `Environment.current`. Beside I recommend using enum values like `Environment.TEST`, `Environment.PRODUCTION`, etc. on the right side of condition check. – topr Dec 04 '12 at 17:05
14

There may be a cleaner way to do this, but I'd got with mapping the error code to a controller and handling the logic there:

class UrlMappings {

   static mappings = {

      "/$controller/$action?/$id?" { constraints {} }

      "/"(view:"/index")

      "403"(controller: "errors", action: "accessDenied")
      "404"(controller: "errors", action: "notFound")
      "405"(controller: "errors", action: "notAllowed")
      "500"(view: '/error')
   }
}

and then create the corresponding controller (grails-app/conf/controllers/ErrorsController.groovy):

import grails.util.Environment

class ErrorsController extends AbstractController {

   def accessDenied = {}

   def notFound = {}

   def notAllowed = {}

   def serverError = {
      if (Environment.current == Environment.DEVELOPMENT) {
         render view: '/error'
      }
      else {
         render view: '/errorProd'
      }
   }
}

You'll need to create the corresponding GSPs in grails-app/views/errors (accessDenied.gsp, notFound.gsp, etc.) and also the new grails-app/views/errorProd.gsp. By routing to a controller method for all error codes you make it easier to add logic to the other error code handlers in the future.

Burt Beckwith
  • 75,342
  • 5
  • 143
  • 156