User macro generates excpetion on some invocations
Asked by Stephen Baxendale:

The user macro show-ancestor-with-label (copy below) generates exceptions (eg, null pointer, array bounds, hibernate) but only on a small number of invocations. It is intended to include a link to the first ancestor it finds with the given label.

Strangely rendering a page that calls the macro \~260 times is successful in approx. 2/3 tries, but on the failed case generates one of the exceptions.

Any suggestions on what may be driving the exceptions (some but not all of the time)?

## [@Param](/t5/user/viewprofilepage/user-id/1345631) Label:title=Label\|type=string\|required=true\|desc=Pages that contain this label should be displayed

##set ( $ancestor = "" )  
#foreach ( $ancestor in $content.getAncestors() )  
#foreach ( $label in $ancestor.getLabels() )  
#if ($label == $paramLabel)  
#contentLink2($ancestor, false, false)  
#break($foreach.parent)  
#end  
#end  
#end


Answers:
author: Stephen Baxendale
body: Thanks [Bill Bailey](https://community.atlassian.com/t5/user/viewprofilepage/user-id/502089), Changing from

# foreach ( $ancestor in $content.getAncestors() ) \*\* causes the semi-random exceptions \*\*

to

#set( $currentPage = $pageManager.getPage($content.id) )  
#foreach ( $ancestor in $currentPage.getAncestors() )

Has cleared up the exceptions !

Not sure exactly why, can only presume that the value of $content is somehow thread unsafe.

Thanks again for the tip Bill.

comments: author: Bill Bailey
body: You're welcome. A guess made because I am not sure what the scope of $content always is. So I try to be as restrictive as possible in my references.

And I learned a new macro: #contentLink2, so thanks for that!


author: Shannon S
body: Stephen,

Is this a User Macro you wrote or did you acquire it from somewhere?

What are the actual error messages from your Confluence server logs?

Shannon

comments: author: Stephen Baxendale
body: Macro is a combination of grabs from other user's macros posted online (ie, picked up the labels and ancestors portions separately), and mixed them locally into a composite.

Exceptions include:

* java.lang.NullPointerException
* java.lang.ArrayIndexOutOfBoundsException
* org.hibernate.. various exceptions

I'm beginning to wonder if there is a thread safety issue - not sure why a macro that is only reading should suffer though?


author: Stephen Baxendale
body: An example exception, which flags the 'getLabels()' call is:

-- url: /confluence/pages/viewpage.action \| page: 13868615 \| traceId: 7f2326fc8022b66b \| userName: noneill \| referer: https://atlas/confluence/login.action?os_  
destination=%2Fpages%2Fviewpage.action%3FspaceKey%3DL200%26title%3D03%2BMonitor\&permissionViolation=true \| action: viewpage  
com.atlassian.core.exception.InfrastructureException: Error occurred rendering template content  
...  
Caused by: org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getLabels' in class com.atlassian.confluence.pages.Page threw exception java.lang.NullPointerException at getRenderedContent\[line 17, column 34\]  
...  
Caused by: java.lang.NullPointerException


author: Bill Bailey
body: What happens with a page with no labels? Are you trapping that event?


author: Stephen Baxendale
body: ![result-on-page-with-no-labels.PNG](https://community.atlassian.com/t5/image/serverpage/image-id/31373iFD95A5C5D4F7FE57/image-size/large?v=v2&px=999 "result-on-page-with-no-labels.PNG")


author: Stephen Baxendale
body: Hi Bill, no seems to work just fine on a page with no labels (see image above).

The odd thing is that it is being called \~1000 times one each load of the page in question, and the exceptions occur roughly 1 in 6 page loads. That's what gets me thinking it may be an asynchronous race condition style cause?


author: Bill Bailey
body: What exactly are you trying to do with this macro, and where is the rest of the macro? I assume line 17 is

```
#foreach ( $label in $ancestor.getLabels() )
```

Could also be the error is actually in the line previous.

When I was writing a custom child page by label macro, I used the following to get the collection of children of page

```
#set( $children =? $currentPage.getSortedChildren() )
```

which did not result in tons of calls. Your call does, depending on where it is.

```
$content.getAncestors() 
```

Which by definition is very recursive
> Gets the list of ancestors of this page (its parents, and its parents parents, right up to the root level of the containing space).

If you are trying to look at parents of a current page, I probably would have used the below instead:

```
$currentPage.getAncestors()
```

To be more restricted in my reference.

What I wrote was inspired by this macro:

<https://github.com/unidwell/confluence-include-child-pages-macro>

It could also give you some hints.


author: Stephen Baxendale
body: Hi Bill,

The macro is trying to find the first parent page of the page it is on with the specified label, and display that page as a hyperlink. The reason is I have a hierarchy of pages that are organised into categories, and at the leafs of the structure I want to display the root page for that item.

The whole macro is right at the top of this thread. I wasn't sure I understood the $content vs $currentPage distinction you we makeing, so modified the macro (see updated macro below), and for an example instance get the following output. Seems to say they are the same thing - do you concur?   

**content** page: ENAP Provisioning from SW-2072 USB v.4 (28639832) **currentPage** page: ENAP Provisioning from SW-2072 USB v.4 (28639832) **ancestorsContent** \[page: Office of the Product Owner v.18 (8028373), page: MSS R2 Product Backlog (PBL) v.72 (8028219), page: 54 MSM Console v.37 (8028229)\] **ancestorsCurrentPage** \[page: Office of the Product Owner v.18 (8028373), page: MSS R2 Product Backlog (PBL) v.72 (8028219), page: 54 MSM Console v.37 (8028229)\] 54 MSM Console

Updated macro:

## Macro title: My Macro  
## Macro has a body: N  
## Body processing: Selected body processing option  
## Output: Selected output option  
##  
## Developed by: Stephen Baxendale  
## Date created: 17 Aug 2018  
## Installed by: Stephen Baxendale  

## [@Param](/t5/user/viewprofilepage/user-id/1345631) Label:title=Label\|type=string\|required=true\|desc=Pages that contain this label should be displayed  

<br />

content $content  
#set( $currentPage = $pageManager.getPage($content.id) )  
currentPage $currentPage  
ancestorsContent $content.getAncestors()  
ancestorsCurrentPage $currentPage.getAncestors()  

<br />

##set ( $ancestor = "" )  
##foreach ( $ancestor in $content.getAncestors() )  
#foreach ( $ancestor in $currentPage.getAncestors() )  

##anc $ancestor  

##set ( $label = "a-very-unusual-and-unlikely-to-match-value" )  
#foreach ( $label in $ancestor.getLabels() )  
##label $label  
#if ($label == $paramLabel)  
#contentLink2($ancestor, false, false)  
#break($foreach.parent)  
#end  
#end  
#end


Tags: atl-adm

confluence-server

server