Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error handling if process definition not found #287

Merged

Conversation

nitram509
Copy link
Collaborator

Since Zeebe Simple Monitor was build to support developers on local testing etc.,
I found myself in situations, where e.g. the process definition was no more available in the database.
This caused the BPMN diagram renderer to fail with exception and was confusing for me as user of Simple Monitor.

Unfortunately, I can't trace back, what caused the fact, that the process was not available, but this would be worth another PR, right? ;)
This PR just makes the renderer more robust in case of in-consistent data.

Additionally, I did replace the throw new RuntimeException() in the ViewController
with proper throw new ResponseStatusException() which will also improve/relate to PR #286 "Feature/error handler2".

Just for the record, the error can be reproduced, if someone deletes the process definition from an existing database.
When requesting a single instance, e.g. curl http://localhost:8082/views/instances/2251799814000236
the response looks like this

{
    "timestamp": "2021-08-09T15:03:04.154+00:00",
    "status": 500,
    "error": "Internal Server Error",
    "trace": "com.samskivert.mustache.MustacheException$Context: No method or field with name 'resource' on line 10
	at com.samskivert.mustache.Template.checkForMissing(Template.java:344)
	at com.samskivert.mustache.Template.getValue(Template.java:247)
	at com.samskivert.mustache.Template.getValueOrDefault(Template.java:292)
	at com.samskivert.mustache.Mustache$VariableSegment.execute(Mustache.java:872)
	at com.samskivert.mustache.Template.executeSegs(Template.java:170)
	at com.samskivert.mustache.Mustache$IncludedTemplateSegment.execute(Mustache.java:831)
	at com.samskivert.mustache.Template.executeSegs(Template.java:170)
	at com.samskivert.mustache.Template.execute(Template.java:137)
	at org.springframework.boot.web.servlet.view.MustacheView.renderMergedTemplateModel(MustacheView.java:80)
	at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:179)
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1393)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1138)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1077)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:764)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Unknown Source)
",
    "message": "No method or field with name 'resource' on line 10",
    "path": "/views/instances/2251799814000236"
}

Replace Runtime Exception with proper ResponseStatusException.
Hint: the later will also improve/relate to PR camunda-community-hub#286 "Feature/error handler2"
@nitram509
Copy link
Collaborator Author

ℹ️
This is, how the implemented warning message will look like.

Screenshot 2021-08-10 at 12 51 57

@celanthe celanthe requested a review from saig0 August 10, 2021 13:33
@saig0
Copy link
Contributor

saig0 commented Aug 16, 2021

@nitram509 awesome. Thank you for this contribution 🎉

I'll review the PR soon 🚀

@CLAassistant
Copy link

CLAassistant commented Aug 26, 2021

CLA assistant check
All committers have signed the CLA.

@nitram509
Copy link
Collaborator Author

@saig0 I did expect, a merge conflict will occur because other PRs made changes on the same code.
I plan to fix the issue and commit&push fixes to this PR.

Copy link
Contributor

@saig0 saig0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 🎉

@nitram509, it seems to work smoothly. Do you still need to adjust this PR?


model.put("resource", WARNING_NO_XML_RESOURCE_FOUND);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could merge the default case in the below Optional chain by using ifPresentOrElse().

processRepository
        .findByKey(instance.getProcessDefinitionKey())
        .map(this::getProcessResource)
        .ifPresentOrElse(
            resource -> model.put("resource", resource),
            () -> model.put("resource", WARNING_NO_XML_RESOURCE_FOUND));

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fine for me ... seems to result in the same behavior and avoiding the exception handling is a bit more elegant.

@nitram509
Copy link
Collaborator Author

@saig0 Looks good to me.
I was irritated, there was a merge conflict, which seems to be gone or my browser cached tricked me ;)

Nothing to do from my side, so good to merge 👍

@saig0 saig0 merged commit 91314bf into camunda-community-hub:master Aug 30, 2021
@saig0 saig0 changed the title Add error handling in case of process definition not found Improve error handling if process definition not found Aug 30, 2021
@nitram509 nitram509 deleted the fix-issue-empty-resource branch February 15, 2022 08:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants