Hi there,
during testing of my app I encountered that one functionality (modifying all pages of a Confluence space) is only working when I use the forge tunnel. I deployed the app already several times and checked that it is up to date on my testing instance. The app is installed in development and production environment. The UI (UI kit) looks fine and everything works, but when I execute this function, nothing happens, whereas it is working correctly when using the tunnel.
Any idea how I could debug this? The production logs in my instance show nothing, unfortunately.
Iβm not much help on the dev side, but as campaign manager for Codegeist, I wanted to provide a little help.
Did you see this other thread?
There are also some feedback items that might help.
https://ecosystem.atlassian.net/browse/FRGE-376
Hi @CarrieMamantov
thanks for the links. I read through them but unfortunately, they donβt help with that problem.
Hey @ij-s
Hmmm this is an interesting one, I got a few questions, when you say the production logs show nothing, what do you mean by that? Is it that no logs came through, or that there is nothing of use from the logs?
If itβs the first case, Iβve got a few more questions, firstly, which functionality are you using to try and attempt to view production logs, is it through admin.atlassian.com
or from forge logs -e production
?
Typically weβd be able to debug your app through their logs, but not having any logs makes it rather difficult Could you please also run forge logs --verbose -e production
and send us through any Request IDs you see? We can check if anything is going wrong with the logging queries from our side and go from there.
Hey @BlairCox
Thanks for your reply. With production logs show nothing I mean that there arenβt any logs. On admin.atlassian.com, I see just this
With forge logs -e production, nothing is displayed at all in the terminal.
I executed βforge logs --verbose -e productionβ. Here is one request ID: bfdf49138dacca17
Hopefully this ID helps to identify what might be the problem.
Was not able to see anything out of the ordinary on our side. For a bit more context, would it be possible to explain what your app is trying to do, and what specifically is going wrong?
Sure, the app should add a label the user inserts to all pages of a Confluence space. It works if the user selects single pages or for all child pages of a certain page. However, if it is selected to add the labe to all pages, the label is just not added. The app donβt return an error, the function is not working.
When running with forge tunnel everything works as expected and also if I log the parameters in the function, everything looks good and I donβt see an issue.
I added some logging to my code:
INFO 2021-09-15T17:54:55.872Z 17fcb5b7-800e-483e-b40c-924d6396996f 3
INFO 2021-09-15T17:54:55.873Z 17fcb5b7-800e-483e-b40c-924d6396996f [ 'tAP' ]
INFO 2021-09-15T17:59:51.756Z 84fc29fe-56b1-4230-b136-4f006b5346d1 3 --> in tunnel, works
INFO 2021-09-15T17:59:51.757Z 84fc29fe-56b1-4230-b136-4f006b5346d1 [ 'label_new' ] --> in tunnel, works
INFO 2021-09-15T18:12:26.203Z 5b34b2a6-f485-482b-9af9-fd90a897bbe4 8
INFO 2021-09-15T18:12:26.211Z 5b34b2a6-f485-482b-9af9-fd90a897bbe4 [ 'label_test' ]
The first line is the number of pages in the space and the second one the array of the label(s) I want to add. Everything looks similar beside that for the two lines in the middle I get the result I expect. For the other attempts, there is no label added.
What difference between tunnel / no tunnel might cause this behavior?
Hi @ij-s , can you post the output of forge install list
?
Hi @PeterYu
here are the results of the forge install list command:
Showing all the current installations of your app:
ββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ¬βββββββββββββ¬ββββββββββ
β Installation ID β Environment β Site β Product β Version β
ββββββββββββββββββββββββββββββββββββββββΌββββββββββββββΌβββββββββββββββββββββββββββββββββββββββΌβββββββββββββΌββββββββββ€
β 867002eb-8845-4dc1-a105-e36b6f4a29c0 β production β dev-ij-solutions.atlassian.net β Confluence β Latest β
ββββββββββββββββββββββββββββββββββββββββΌββββββββββββββΌβββββββββββββββββββββββββββββββββββββββΌβββββββββββββΌββββββββββ€
β 44b3ef3d-2c3f-43c8-b697-448a49bad82a β production β dev-ij-solutions.atlassian.net β Identity β Latest β
ββββββββββββββββββββββββββββββββββββββββΌββββββββββββββΌβββββββββββββββββββββββββββββββββββββββΌβββββββββββββΌββββββββββ€
β a78fc586-2058-4546-ba4e-595019e51c9d β production β xyz-test.atlassian.net β Confluence β Latest β
ββββββββββββββββββββββββββββββββββββββββΌββββββββββββββΌβββββββββββββββββββββββββββββββββββββββΌβββββββββββββΌββββββββββ€
β e766bc5a-3b06-43c3-83d3-b6a3d2212afe β development β cloud-dev-ij-solutions.atlassian.net β Confluence β Latest β
ββββββββββββββββββββββββββββββββββββββββΌββββββββββββββΌβββββββββββββββββββββββββββββββββββββββΌβββββββββββββΌββββββββββ€
β 90c158f6-b3d0-4f46-9edf-6eed56079a5e β development β cloud-dev-ij-solutions.atlassian.net β Identity β Latest β
ββββββββββββββββββββββββββββββββββββββββΌββββββββββββββΌβββββββββββββββββββββββββββββββββββββββΌβββββββββββββΌββββββββββ€
β 2e6e37dc-2189-4824-916d-40d07128fdd4 β development β dev-ij-solutions.atlassian.net β Confluence β Latest β
ββββββββββββββββββββββββββββββββββββββββΌββββββββββββββΌβββββββββββββββββββββββββββββββββββββββΌβββββββββββββΌββββββββββ€
β 0db1621b-4ab7-4e91-8dec-0d8103c35d0e β development β dev-ij-solutions.atlassian.net β Identity β Latest β
I replace the one instance name that is not one of my own testing instances with xyz.
Hi @ij-s
In order to continue some investigation on our side, do you mind sharing the appId
of your app?
If you could also share some of your code, it would be great to try to replicate the scenario on our side.
Thanks
Hi @XavierCaron
the app id is ari:cloud:ecosystem::app/adf049d1-a1d9-484f-ba73-83f16817b440
Here is some sample code I extracted from the apps code. It is the part which is only working when there is a tunnel.
import api, { route } from "@forge/api";
const getSpacePages = async (spaceKey) => {
const res = await api
.asUser()
.requestConfluence(route`/rest/api/content?spaceKey=${spaceKey}`, {
headers: {
'Accept': 'application/json'
}
});
const data = await res.json();
return data.results;
};
export async function addLabels(spaceKey, labels) {
let result;
let body;
let response;
let spacePages;
let labelsToAdd = new Array();
if(labels.length > 0){
if(labels.indexOf(" ") != -1){
labels.split(" ").map( lbl => labelsToAdd.push(lbl.trim()) )
} else {
labelsToAdd.push(labels.trim())
}
spacePages = await getSpacePages(spaceKey);
if(spacePages.length > 0){
async function bulkAddLabels() {
try {
return await Promise.all(
labelsToAdd.map( (label) => {
spacePages.map( (page) => {
body = `[
{
"prefix": "global",
"name": "`+label.trim()+`"
}
]`;
api.asUser().requestConfluence(route`/rest/api/content/${page.id}/label`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: body
}).then(
(response) => response.json()
)
})
})
);
} catch (error) {
return error.message;
}
}
result = await bulkAddLabels();
}
return result;
} else {
return "no labels provided"
}
}
I hope this helps for further investigation.
Hi @ij-s
Thanks for the added details.
From my investigation, I could not see any error regarding your app invocations. As you mentioned, the app actually succeeds, although does not work βproperlyβ.
After looking into your code sample, I think the following might be the issue: you are not awaiting the promises inside the .map()
part (second level map) properly.
This means that under the hood, the app is invoked but then finishes its work before the promises all get fired / finish. This would explain that no result gets logged and that the invocation succeeds.
Why is it different in tunnel? I suspect that your tunnel stays open even after the invocation is finished, so it gives the promises time to actually fire / resolve, hence the seen behaviour.
Here is a code sample where the promises are properly awaited:
const wait = () => new Promise((resolve) => setTimeout(resolve, 500));
const labelsToAdd = ['label-one', 'label-two'];
const spacePages = ['sp-one', 'sp-two'];
async function bulkAddLabels() {
try {
return Promise.all(
labelsToAdd.map((label) => {
console.log(`handling label ${label}`);
return Promise.all(
spacePages.map((page) => {
console.log(`handling page ${page}`);
return wait().then(async () => {
await wait();
console.log(`handling page ${page} - done`)
});
})
)
})
);
} catch (error) {
return error.message;
}
}
And another one which might look simpler (less Promises.all()):
async function bulkAddLabels() {
try {
const promises = [];
labelsToAdd.map((label) => {
console.log(`handling label ${label}`);
spacePages.map((page) => {
console.log(`handling page ${page}`);
promises.push(wait().then(async () => {
await wait();
console.log(`handling page ${page} - done`);
}));
});
});
return await Promise.all(promises);
} catch (error) {
return error.message;
}
}
Let me know if this helps!
Hi @XavierCaron
thanks a lot for investigating this issue. I applied the code snippet you suggested to my app and the problem doesnβt occur again
Everything is working as expected now.