fix: improve JiraService pagination handling
- Updated JiraService to use `nextPageToken` for pagination instead of `startAt`, aligning with the latest API documentation. - Enhanced logging for better visibility during ticket retrieval, including page number and pagination status. - Implemented safety checks to prevent infinite loops and added a limit for ticket retrieval.
This commit is contained in:
@@ -65,25 +65,30 @@ export class JiraService {
|
||||
const fields = ['id', 'key', 'summary', 'description', 'status', 'priority', 'assignee', 'project', 'issuetype', 'duedate', 'created', 'updated', 'labels'];
|
||||
|
||||
const allIssues: unknown[] = [];
|
||||
let startAt = 0;
|
||||
const maxResults = 100; // Taille des pages
|
||||
let hasMorePages = true;
|
||||
let nextPageToken: string | undefined = undefined;
|
||||
let pageNumber = 1;
|
||||
|
||||
console.log('🔄 Récupération paginée des tickets Jira...');
|
||||
console.log('🔄 Récupération paginée des tickets Jira (POST /search/jql avec tokens)...');
|
||||
|
||||
while (hasMorePages) {
|
||||
const requestBody = {
|
||||
while (true) {
|
||||
console.log(`📄 Page ${pageNumber} ${nextPageToken ? `(token présent)` : '(première page)'}`);
|
||||
|
||||
// Utiliser POST /rest/api/3/search/jql avec nextPageToken selon la doc officielle
|
||||
const requestBody: any = {
|
||||
jql,
|
||||
fields
|
||||
fields,
|
||||
maxResults: 50
|
||||
};
|
||||
|
||||
console.log(`📄 Page ${Math.floor(startAt / maxResults) + 1} (tickets ${startAt + 1}-${startAt + maxResults})`);
|
||||
if (nextPageToken) {
|
||||
requestBody.nextPageToken = nextPageToken;
|
||||
}
|
||||
|
||||
const response = await this.makeJiraRequest(
|
||||
`/rest/api/3/search/jql?startAt=${startAt}&maxResults=${maxResults}`,
|
||||
'POST',
|
||||
requestBody
|
||||
);
|
||||
console.log(`🌐 POST /rest/api/3/search/jql avec ${nextPageToken ? 'nextPageToken' : 'première page'}`);
|
||||
|
||||
const response = await this.makeJiraRequest('/rest/api/3/search/jql', 'POST', requestBody);
|
||||
|
||||
console.log(`📡 Status réponse: ${response.status}`);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
@@ -96,7 +101,11 @@ export class JiraService {
|
||||
throw new Error(`Erreur API Jira: ${response.status} ${response.statusText}. Détails: ${errorText.substring(0, 200)}`);
|
||||
}
|
||||
|
||||
const data = await response.json() as { issues: unknown[], total: number, maxResults: number, startAt: number };
|
||||
const data = await response.json() as {
|
||||
issues: unknown[],
|
||||
nextPageToken?: string,
|
||||
isLast?: boolean
|
||||
};
|
||||
|
||||
if (!data.issues || !Array.isArray(data.issues)) {
|
||||
console.error('❌ Format de données inattendu:', data);
|
||||
@@ -104,17 +113,26 @@ export class JiraService {
|
||||
}
|
||||
|
||||
allIssues.push(...data.issues);
|
||||
console.log(`✅ ${data.issues.length} tickets récupérés (total: ${allIssues.length}/${data.total || '?'})`);
|
||||
console.log(`✅ ${data.issues.length} tickets récupérés (total accumulé: ${allIssues.length})`);
|
||||
console.log(`🔍 Pagination info:`, {
|
||||
issuesLength: data.issues.length,
|
||||
hasNextPageToken: !!data.nextPageToken,
|
||||
isLast: data.isLast,
|
||||
pageNumber
|
||||
});
|
||||
|
||||
// Vérifier s'il y a plus de pages
|
||||
hasMorePages = data.issues.length === maxResults && allIssues.length < (data.total || Number.MAX_SAFE_INTEGER);
|
||||
startAt += maxResults;
|
||||
// Vérifier s'il y a plus de pages selon la doc officielle
|
||||
if (data.isLast === true || !data.nextPageToken) {
|
||||
console.log('🏁 Dernière page atteinte (isLast=true ou pas de nextPageToken)');
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(`📊 Pagination: hasMorePages=${hasMorePages}, startAt=${startAt}, maxResults=${maxResults}`);
|
||||
nextPageToken = data.nextPageToken;
|
||||
pageNumber++;
|
||||
|
||||
// Sécurité: éviter les boucles infinies (augmenté avec la nouvelle taille de page)
|
||||
if (allIssues.length > 10000) {
|
||||
console.warn('⚠️ Limite de sécurité atteinte (10000 tickets). Arrêt de la pagination.');
|
||||
// Sécurité: éviter les boucles infinies
|
||||
if (allIssues.length >= 10000) {
|
||||
console.warn(`⚠️ Limite de sécurité atteinte (${allIssues.length} tickets). Arrêt de la pagination.`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user