I implemented a controller that handles HTTP error codes:
class ErrorController {
// 500
def internalserver = {
}
// 504
def timeout = {
}
// 404
def notfound = {
// just testing the values
log.debug "params: ${params}"
log.debug "response: ${response}"
log.debug "url: ${response.redirectURL}"
log.debug "object: ${response.content}"
}
// 403
def forbidden = {
}
}
Note that i already updated the UrlMappings too.
"500"(controller:'error', action:'internalserver')
"504"(controller:'error', action:'timeout')
"404"(controller:'error', action:'notfound')
"403"(controller:'error', action:'forbidden')
Is there a way to retrieve details inside each action?
i.e. for 404, the URL that was requested. for 500, the exception message or something.
looks like by simply referring to:
grails-app/views/error.gsp
will reveal all needed information.
Related
My Grails 3.2.3 app is running on port 9000 and I'm doing a GET request to the URL /api/mail/getUnreadCount but I'm getting a 404 error to that URL.
My URLMapping.groovy having:
get "/api/$controller(.$format)?"(action: "index")
get "/api/$controller/$id(.$format)?"(action: "show")
"/api/$controller/$action?/$id?(.$format)?" {
constraints {
// apply constraints here
}
}
Also help me, how we can enable Grails URL mapping logs?
Update 1
class MailController {
static allowedMethods = [index: "GET", getUnreadCount: "GET"]
.....
.......
def getUnreadCount() {
User currentUserInstance = springSecurityService.getCurrentUser()
List counts = userService.getUnreadCounts(currentUserInstance)
respond(counts)
}
}
It is expected that you have getUnreadCount.gsp in views/mail directory to get the output from respond
.. and for the code you provided, if you dont have any view, you should get Error 500 not 404.
In your code, put
formats: ['xml', 'json']
or explicitely mention view
view: "showCount"
or try render method instead
Update
Btw, please remove
get "/api/$controller/$id(.$format)?"(action: "show")
When you hit /api/mail/getUnreadCount, this mapping causes $id = getUnreadCount, and you don't have any action show in your controller, which generates 404 error.
I'm using grails 2.3.7 with SpringSecurityCore 2.0 .. I have two separate signon screens tailored for specific devices with the appropriate one triggered by accessing a specific controller. To do this I customized the loginController ..
/**
* Show the login page.
*/
def auth() {
def config = SpringSecurityUtils.securityConfig
if (springSecurityService.isLoggedIn()) {
redirect uri: config.successHandler.defaultTargetUrl
return
}
String whereFrom = session.SPRING_SECURITY_SAVED_REQUEST.requestURI
def rdt = whereFrom.contains('RDT')
// Redirect for RDT as required ..
String view = rdt ? 'rauth' : 'auth'
String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
session.rdt = rdt
render view: view, model: [postUrl: postUrl,
rememberMeParameter: config.rememberMe.parameter]
}
which seems to work well .. On logout I want again to redirect to an appropriate screen .. I'm trying to use the session attribute I store on login along with a (admittedly old) link I found (http://grails.1312388.n4.nabble.com/Parameter-quot-logoutSuccessUrl-quot-in-spring-security-core-td2264147.html) to redirect back to an appropriate page ..
/**
* Index action. Redirects to the Spring security logout uri.
*/
def index() {
if (!request.post && SpringSecurityUtils.getSecurityConfig().logout.postOnly) {
response.sendError HttpServletResponse.SC_METHOD_NOT_ALLOWED // 405
return
}
// TODO put any pre-logout code here
def rdt = session.rdt
session.rdt = null
// redirect uri: "/j_spring_security_logout?spring-security-redirect=$logoutUrl"
if (rdt) {
def link = g.createLink(controller: "RDT")
def redirectUrl = "${SpringSecurityUtils.securityConfig.logout.filterProcessesUrl}?spring-security-redirect=${link}"
redirectStrategy.sendRedirect request, response, redirectUrl
} else {
redirectStrategy.sendRedirect request, response, SpringSecurityUtils.securityConfig.logout.filterProcessesUrl // '/j_spring_security_logout'
}
response.flushBuffer()
}
Both options return me to the 'default' auth login screen and not my alternate rauth one even with the addition of the extra parameter .. How can I route back to an appropriate screen ?? Thanks
In the end I manually set the session variables to null, invalidate the session and a standard redirect ... works ..
When I run this code:
package nexmo
class SmsControllerController {
// Inject the service
def nexmoService
def index() {
def smsResult
def callResult
try {
// Send the message "What's up?" to 1-500-123-4567
smsResult = nexmoService.sendSms("61451062006", "What's up?")
// Call the number and tell them a message
callResult = nexmoService.call("61451062006", "Have a great day! Goodbye.")
catch (NexmoException e ) {
// Handle error if failure
}
}
}
}
I get the following error message:
Error Compilation error: startup failed:
C:\nexmo-master\grails-app\controllers\nexmo\SmsController.groovy: 19: unexpected token: catch # line 19, column 13.
catch (NexmoException e ) {
^
How do I resolve this issue?
Try closing the try statement before you the catch statement.
try {
// Send the message "What's up?" to 1-500-123-4567
smsResult = nexmoService.sendSms("61451062006", "What's up?")
// Call the number and tell them a message
callResult = nexmoService.call("61451062006", "Have a great day! Goodbye.")
}
catch (NexmoException e ) {
// Handle error if failure
}
I am using grails-jaxrs for exposing an api which accepts multipart/form-data..
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(['application/json'])
#Path('/addMessage')
ChatMessage addChatMessageWithAttachment(#Context HttpServletRequest req) {
log.debug "> addChatMessageWithAttachment"
def fileStores = []
def chatMessage
GrailsWebRequest request = WebUtils.retrieveGrailsWebRequest()
def params = request.getParams()
if (!(params.messageBody.length() > 0)) {
log.error("Empty message body")
throw new LocalisedException(ErrorCode.CHAT_MESSAGE_CREATE_FAILED)
}
}
The implementation is working properly as expected. I am able to send form-data (with file and other parameters successfully.
Now I am trying to implement integration test for above logic.
I am using IntegrationTestCase to achieve this.. so my code snippet is as below:
class ChatMessageResourceV1Tests extends IntegrationTestCase{
//other implementation and setup ommited
#Test
void "Create new chat message for event id - customer user"() {
def headers = ['Content-Type': 'multipart/form-data', 'Accept': 'application/json']
def data = "My message..."
def cm = new ChatMessage(messageBody: data)
def content = "{'eventId':'$event.id','messageBody':'My message...'}"
sendRequest("/api/v1/chatMessage/addMessage", 'POST', headers, content.bytes)
assertEquals(200, response.status)
}
}
When I run the test.. I can see the call reaches inside the API method.. But however, the parameter messageBody is coming as null and exception is being thrown.
I have tried every possible combination of test.. But no luck.
Any help would be appreciated.
"404" (controller: 'error', action: 'pageNotFound')
Any changes to response.status inside the pageNotFound action is reverted back to 404 before the response is sent to the client. Is it possible to work around this some way? I would like to be able to change it to 410 when I detect that the resource has been deleted or 301 when it's moved permanently.
If that's not working try this in your error controller:
class ErrorController {
def notFound = {
redirect( action: 'gone')
}
def gone= {
response.sendError(410, "Gone")
}
}
Try setting the header yourself manually by response.setHeader()