Grails validate runtime error - validation

I use grails validate() function in my very simple update action inside a controller. The problem is very starnge. validate() is not executed at all and giving no error and stopping the execution. I am using Grails 2.3.3
Only the log gives the following error:
Runtime error executing action
Here is my controller code:
def update() {
println(params);
def study = Study.findByUid(params.uid);
study.description = params.description;
println(study); //study is found and printed
study.validate();
println("here"); //not executed and code below is also not executed
if(study.hasErrors()){
study.errors.each{
println it
}
render 'not saved!'
}
if (!study.save()) {
println("Error");
withFormat renderInternalError
}
else {
render "OK"
}
}
Stacktrace:
Request received for '/study/update':
org.apache.catalina.connector.RequestFacade#1eaba95c
servletPath:/study/update
pathInfo:null
Security filter chain: [
SecurityContextPersistenceFilter
MutableLogoutFilter
RequestHolderAuthenticationFilter
SecurityContextHolderAwareRequestFilter
GrailsRememberMeAuthenticationFilter
GrailsAnonymousAuthenticationFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2013-11-27 11:56:04,738 [http-bio-8080-exec-9] DEBUG filter.GrailsRememberMeAuthenticationFilter - SecurityContextHolder not populated with remember-me token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken#f6816ea3: Principal: grails.plugin.springsecurity.userdetails.GrailsUser#b29dace9: Username: creator#example.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#1c07a: RemoteIpAddress: 127.0.0.1; SessionId: A1813ED8541AAC773CEF349475DB24A2; Granted Authorities: ROLE_USER'
2013-11-27 11:56:04,738 [http-bio-8080-exec-9] DEBUG filter.GrailsAnonymousAuthenticationFilter - SecurityContextHolder not populated with anonymous token, as it already contained: '{0}'
2013-11-27 11:56:04,740 [http-bio-8080-exec-9] TRACE intercept.AnnotationFilterInvocationDefinition - new candidate for '{0}': '{1}':{2}
2013-11-27 11:56:04,740 [http-bio-8080-exec-9] TRACE intercept.AnnotationFilterInvocationDefinition - config for '{0}' is '{1}':{2}
2013-11-27 11:56:04,741 [http-bio-8080-exec-9] TRACE core.StandardWrapper - Returning non-STM instance
2013-11-27 11:56:04,743 [http-bio-8080-exec-9] DEBUG simple.MemoryPageFragmentCachingFilter - No cacheable annotation found for POST:/hdspro/grails/study/update.dispatch [controller=study, action=update]
2013-11-27 11:56:05,651 [http-bio-8080-exec-9] DEBUG errors.GrailsExceptionResolver - Resolving exception from handler [org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController#98f1784]: org.codehaus.groovy.grails.web.servlet.mvc.exceptions.ControllerExecutionException: Executing action [update] of controller [com.digithurst.hdspro.StudyController] caused exception: Runtime error executing action
2013-11-27 11:56:05,651 [http-bio-8080-exec-9] DEBUG errors.GrailsExceptionResolver - Resolving to view '/error' for exception of type [org.codehaus.groovy.grails.web.servlet.mvc.exceptions.ControllerExecutionException], based on exception mapping [java.lang.Exception]
2013-11-27 11:56:05,651 [http-bio-8080-exec-9] DEBUG errors.GrailsExceptionResolver - Exposing Exception as model attribute 'exception'
2013-11-27 11:56:05,951 [http-bio-8080-exec-9] ERROR errors.GrailsExceptionResolver - StackOverflowError occurred when processing request: [POST] /hdspro/study/update - parameters:
acessionNumber: 3
uid: 3
description: Elbogen123
Stacktrace follows:
org.codehaus.groovy.grails.web.servlet.mvc.exceptions.ControllerExecutionException: Executing action [update] of controller [com.digithurst.hdspro.StudyController] caused exception: Runtime error executing action
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at grails.plugin.springsecurity.web.filter.DebugFilter.invokeWithWrappedRequest(DebugFilter.java:102)
at grails.plugin.springsecurity.web.filter.DebugFilter.doFilter(DebugFilter.java:69)
......
/
Study class:
class Study extends Document {
String uid
String description
String accessionNumber
Date date
String toString(){
return "Study" + uid + ": " + description;
}
}

From the comments I've read, you say you did not add any constraints to the domain class. From what I know validate() uses these constraints to check if your instance has errors. Ex:
class CartType {
String name
static constraints = {
name blank: false, nullable:false, maxSize: 50
}
String toString(){name}
}
In this example class we have a cartType. When we call validate() grails will check the constraint block. In this case it will check that the name is not left blank in the form, it cannot be null and that it's max size is 50 characters.
Note: The constraints block can also help grails build the database.
If you did not declare any contraints validate() will not have anything to check against. You will also most likely get an error when a value is null, because, by default, nullable is set to false.

Related

how to pass a parameter in the Header with multipartFormData

#PostMapping(value = "/uploadCV" , consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<?> uploadCV(#RequestHeader("token") String token,
#RequestParam("file") MultipartFile cvFile) throws Exception {
log.info(token + cvFile.getOriginalFilename()));
return curriculumService.addCurriculum(token, pdfFile);
}
If i use MediaType.MULTIPART_FORM_DATA_VALUE don't get the value "token" :
2022-11-11 16:13:28.040 WARN 7283 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingRequestHeaderException: Required request header 'token' for method parameter type String is not present]
If i use MediaType.MULTIPART_MIXED_VALUE don't get file:
org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
how can i do?
The code that you have written with MediaType.MULTIPART_FORM_DATA_VALUE is absolutely correct. It is very clear from error message what is the issue.
2022-11-11 16:13:28.040 WARN 7283 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingRequestHeaderException: Required request header 'token' for method parameter type String is not present]
Issue:
Code is expecting header name with key token should present in the request but it is not present.
Solution:
Please add header name with key token like this and try again.

Spring WebFlux - WebGraphQlInterceptor has empty request data

I would need to retrieve data from query headers for use in the GraphQl query controller. I searched around a bit and found the WebGraphQlInterceptor, but realized that when the WebGraphQlRequest argument is invoked it is completely devoid of information.
For example, this code:
#Component
class WebRequestInterceptor : WebGraphQlInterceptor {
val logger: Logger by lazy { LoggerFactory.getLogger(WebRequestInterceptor::class.java) }
override fun intercept(request: WebGraphQlRequest, chain: WebGraphQlInterceptor.Chain): Mono<WebGraphQlResponse> {
logger.info("URI", request.uri.toString())
logger.info("HEADERS", request.headers.toString())
logger.info("DOCUMENT", request.document)
return chain.next(request)
}
}
Returns:
2022-09-12 10:57:11.747 INFO 1 --- [or-http-epoll-1] b.s.b.gateway.auth.WebRequestInterceptor : URI *empty string*
2022-09-12 10:57:11.748 INFO 1 --- [or-http-epoll-1] b.s.b.gateway.auth.WebRequestInterceptor : HEADERS *empty string*
2022-09-12 10:57:11.748 INFO 1 --- [or-http-epoll-1] b.s.b.gateway.auth.WebRequestInterceptor : DOCUMENT *empty string*
P.S. The same thing happens if I try to log a single headers element using the request.headers.getFirst(..) function.

AbpApiExceptionFilterAttribute - A value is required but was not present in the request

I have a webapi controller like below:
[ResponseType(typeof(SampleDto))]
public IHttpActionResult GetSample(string name, string guid)
and the request take name and guid as query string like:
http://www.example.com/api/Controller1/GetSample?name=james&guid=
the guid is empty.
When I issue the request, there is an Error:
WARN 2018-09-29 07:04:21,361 [18 ] nHandling.AbpApiExceptionFilterAttribute - Method arguments are not valid! See ValidationErrors for details.
Abp.Runtime.Validation.AbpValidationException: Method arguments are not valid! See ValidationErrors for details.
WARN 2018-09-29 07:04:21,361 [18 ] nHandling.AbpApiExceptionFilterAttribute - There are 2 validation errors:
WARN 2018-09-29 07:04:21,361 [18 ] nHandling.AbpApiExceptionFilterAttribute - A value is required but was not present in the request. (guid.String)
WARN 2018-09-29 07:04:21,361 [18 ] nHandling.AbpApiExceptionFilterAttribute - A value is required but was not present in the request. (guid.String)
Where can I change the validation rule?

About Spring WebClient on external onTerminate event

I'm running a spring-boot v2.0.3 tomcat-embedded webserver 8.5.31, to Serve Spring Webflux REST services.
One of those REST services calls to another, external REST Webservice.
public Mono<ServerResponse> select(ServerRequest request) {
return request.principal().cast(Authentication.class)
.flatMap(principal ->
client.get().uri(f -> buildUri(request, principal, request.queryParams(), f))
.exchange())
.flatMap((ClientResponse mapper) ->
ServerResponse.status(mapper.statusCode())
.headers(c -> mapper.headers().asHttpHeaders().forEach(c::put))
.body(mapper.bodyToFlux(DataBuffer.class)
.delayElements(Duration.ofSeconds(10))
.doOnCancel(() -> log.error("Cancelled client"))
.doOnTerminate(() -> log.error("Terminated client")), DataBuffer.class))
.doOnTerminate(() -> log.error("Termination called"));
}
If a browser calls my REST-Service, and after a short while cancels the connection, I can see the outer "Termination called" event, and that the client was terminated also. But the client termination seems to trigger an error in tomcat:
2018-07-25 12:50:42.860 DEBUG 12084 --- [ elastic-3] org.example.search.security.UserManager : Authorizing org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken#809aec11: Principal: cn=dv dbsearch client, ou=dbsearch, o=example, l=eb, st=unknown, c=de; Credentials: [PROTECTED]; Authenticated: false; Details: null; Not granted any authorities
2018-07-25 12:50:42.864 DEBUG 12084 --- [ elastic-3] org.example.search.security.UserManager : Successfully authorized: org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken#c03925ec: Principal: org.springframework.security.core.userdetails.User#809aec0e: Username: cn=dv dbsearch client, ou=dbsearch, o=example, l=eb, st=unknown, c=de; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_ADMIN
2018-07-25 12:50:45.470 ERROR 12084 --- [ctor-http-nio-4] c.d.s.s.h.SolrSelectRequestHandler : Termination called
2018-07-25 12:51:15.562 ERROR 12084 --- [ parallel-3] c.d.s.s.h.SolrSelectRequestHandler : Terminated client
2018-07-25 12:51:15.625 ERROR 12084 --- [nio-8443-exec-2] o.s.w.s.adapter.HttpWebHandlerAdapter : Unhandled failure: Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen, response already set (status=200)
2018-07-25 12:51:15.628 WARN 12084 --- [nio-8443-exec-2] o.s.h.s.r.ServletHttpHandlerAdapter : Handling completed with error: Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen
2018-07-25 12:51:15.652 ERROR 12084 --- [nio-8443-exec-2] o.a.catalina.connector.CoyoteAdapter : Exception while processing an asynchronous request
java.lang.IllegalStateException: Calling [asyncError()] is not valid for a request with Async state [DISPATCHING]
at org.apache.coyote.AsyncStateMachine.asyncError(AsyncStateMachine.java:424)
at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:470)
at org.apache.coyote.Request.action(Request.java:431)
at org.apache.catalina.core.AsyncContextImpl.setErrorState(AsyncContextImpl.java:388)
at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:176)
at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:232)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Sorry for the german errormessages, it means "client abortet connection".
I don't really have a problem with this errormessage per se, it's just, that my buffers in spring's Webclient don't seem to be cleared up (the log I did not reproduce locally, so it has diferent timestamps):
2018-07-23 08:44:36.892 ERROR 22707 — [reactor-http-nio-5] io.netty.util.ResourceLeakDetector : LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records:
Created at:
io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:331) io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:185)
So here the question: How can I cleanly end the WebClient connection, when the request to my REST-Service is cancelled?
I can't really say for sure about that exception message, but I know Tomcat improved this in the 8.5.x generation. Which version are you using? If you can provide a consistent way to reproduce this with a minimal application, you could create a new issue in jira.spring.io on Spring Framework, or Tomcat itself if you managed to reproduce it without Spring (although it should be a hard one to reproduce).
Now about releasing DataBuffer instances - DataBuffer instances can be pooled, depending on the implementation. Here the WebClient is using Netty, which is pooling buffers. So they need to be released when they're no longer used.
Looking at your implementation, I think those unreleased buffers come from this:
the WebClient is fetching data from the remote endpoint and creating DataBuffer instances
various Reactor operators along the way are buffering those using internal queues (depending on the prefetching and the operators used, the amount of queued buffers can vary)
when the subscriber fails or cancels, those buffers sitting in internal queues are not released as they should.
Currently Reactor does not offer a hook point to reach those objects in those error cases. But this is a brand new feature that's been added in Reactor core 3.2.0. This will be leveraged internally by Spring Framework with SPR-17025. Please follow this issue - your use case might be handy when it comes to testing the fix.

How to debug parameters sent in Grails

Grails is so nice to append the parameters sent to console output in the case of an error:
2011-05-23 12:17:05,173 [http-8080-5] ERROR errors.GrailsExceptionResolver - Exception occurred when processing request: [POST] / - parameters:
maps: on
maps: on
maps: on
maps:
_isPublic:
description: test
name: set1
isPublic: on
Stacktrace follows:
...
But how can I tell it to always show me which parameters are sent (like in Rails, for example)?
My current log4j configuration looks as follows:
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
warn 'org.mortbay.log'
I don't believe Grails itself supports logging the request parameters for each request. However, you can easily implement this yourself in a filter:
package com.example
class MyFilters {
private static final log = org.apache.commons.logging.LogFactory.getLog(this)
def filters = {
paramLogger(controller:'*', action:'*') {
before = {
log.debug "request params: $params"
}
}
}
}
Remember to enable debug logging for this filter in `Config.groovy by adding
debug com.example
to the log4j closure
You probably want to get more output from org.codehaus.groovy.grails.web so set that one to a lower level (debug or trace)

Resources