We have implemented a Listener Script to sum up story points to the Epic. The script is working as expected, but we are seeing some errors in the logs. The error occurs against some issues, but not all. What is the best way to "debug" where these errors are coming from? Not knowing what is causing the errors, I am not sure how to debug. I think it may be occurring against Stories that have a Story Point of 0, but I am not sure. The error we see is:CorrelationId: d09ae111-14a2-4e5d-b2e4-357b61af6377RUN Script identifier: 71a41f53-a120-410b-b762-7be45295cd66 com.adaptavist.sr.cloud.events.WebhookExecution (jira:issue_updated webhook fired for issue ST-1936)Script name: Sum child story points and add to parent Epic Took: 616ms Logs:2020-12-11 16:03:33.109 ERROR - Cannot invoke method size() on null object2020-12-11 16:03:33.170 ERROR - Class: com.adaptavist.sr.cloud.events.WebhookExecution, Config: null
The script itself does not fail, and the Story Points are summed, it's just logging an error that, if I can "catch", I could resolve/avoid the error in the log.
Any suggestion on how to enhance logging/debugging?
The script that is running:
// Get the ID of the fields for Story Points and Epic Link def storyPointsField = get("/rest/api/2/field").asObject(List).body.find {(it as Map).name == 'Story Points'}.id def epicLinkField = get("/rest/api/2/field").asObject(List).body.find {(it as Map).name == 'Epic Link'}.id // Retrieve all the issues in this issues' Epic def epicKey = issue.fields."${epicLinkField}" def issuesInEpic = get("/rest/agile/1.0/epic/${epicKey}/issue") .asObject(Map) .body .issues as List<Map> logger.info("Total issues in Epic for ${epicKey}: ${issuesInEpic.size()}") // Sum the estimates def estimate = issuesInEpic.collect { Map issueInEpic -> issueInEpic.fields."${storyPointsField}" ?: 0 }.sum() logger.info("Summed estimate: ${estimate}") // Now update the parent Epic def result = put("/rest/api/2/issue/${epicKey}") .queryString("overrideScreenSecurity", Boolean.TRUE) .header('Content-Type', 'application/json') .body([ fields: [ "${storyPointsField}": estimate, ] ]) .asString() // check that updating the parent issue worked assert result.status >= 200 && result.status < 300
Hi @Jeanne Howe I checked the documentation (https://scriptrunner-docs.connect.adaptavist.com/jiracloud/logs.html) and it looks like there is Logs screen in the script runner:
You can log messages in your script using following methods:
Hi Martin,
I think the issue causing the error is that some Stories do not have an Epic Link.
I know I can add a condition to be evaluated before the listener runs. Do you know what the format of the condition would be if I wanted to verify the issue has an Epic Link? Would it be something like this:
issue.issueType.name.match('^(Story|Bug|Task)$') != null and link.issueLinkType.name.match == ('^(Epic-Story Link)$')
Can this be done as a condition, or do I need some type of IF statement in the listener script itself?
Hi @Jeanne Howe sorry, I thought you needed to point to a place where the log message are displayed.
When I'm checking your code and error message, I would suggest you to wrap following part of code with IF condition:
if(issuesInEpic){logger.info("Total issues in Epic for ${epicKey}: ${issuesInEpic.size()}")// Sum the estimatesdef estimate = issuesInEpic.collect { Map issueInEpic -> issueInEpic.fields."${storyPointsField}" ?: 0}.sum()logger.info("Summed estimate: ${estimate}")// Now update the parent Epicdef result = put("/rest/api/2/issue/${epicKey}") .queryString("overrideScreenSecurity", Boolean.TRUE) .header('Content-Type', 'application/json') .body([ fields: [ "${storyPointsField}": estimate, ] ]) .asString()// check that updating the parent issue workedassert result.status >= 200 && result.status < 300}
Is it what you needed? Or can you clarify it further?
Hi @Martin Bayer _MoroSystems_ s_r_o__ Thank you. I did something very similar to this (once I figured out the IF statement). My code looks like this:
// Get the ID of the fields for Story Points and Epic Linkdef storyPointsField = get("/rest/api/2/field").asObject(List).body.find {(it as Map).name == 'Story Points'}.iddef epicLinkField = get("/rest/api/2/field").asObject(List).body.find {(it as Map).name == 'Epic Link'}.id
// Retrieve all the issues in this issues' Epicdef epicKey = issue.fields."${epicLinkField}"logger.info("Epic Key is: " + epicKey)
if (epicKey != null) { //This is to check if the event.issue's epic is nulldef issuesInEpic = get("/rest/agile/1.0/epic/${epicKey}/issue").asObject(Map).body.issues as List<Map>logger.info("Total issues in Epic for ${epicKey}: ${issuesInEpic.size()}")
// Sum the estimatesdef estimate = issuesInEpic.collect { Map issueInEpic ->issueInEpic.fields."${storyPointsField}" ?: 0}.sum()logger.info("Summed estimate: ${estimate}")
// Now update the parent Epicdef result = put("/rest/api/2/issue/${epicKey}").queryString("overrideScreenSecurity", Boolean.TRUE).header('Content-Type', 'application/json').body([fields: ["${storyPointsField}": estimate,]]).asString()
// check that updating the parent issue workedassert result.status >= 200 && result.status < 300}
It looks like you're new here. Sign in or register to get started.