mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-29 19:10:43 +08:00
test: Retry SSE webhook setup on 404 (#28961)
Co-authored-by: Danny Martini <danny@n8n.io> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Danny Martini
Claude Opus 4.7
parent
40da23f688
commit
334ce39f65
@@ -2,12 +2,15 @@ import type { APIResponse } from '@playwright/test';
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { setTimeout as wait } from 'node:timers/promises';
|
||||
|
||||
import type { ApiHelpers } from './api-helper';
|
||||
import { N8N_AUTH_COOKIE } from '../config/constants';
|
||||
|
||||
type HttpMethod = 'GET' | 'POST' | 'DELETE';
|
||||
|
||||
class SseNotFoundError extends Error {}
|
||||
|
||||
interface SseConnection {
|
||||
sessionId: string;
|
||||
postUrl: string;
|
||||
@@ -176,6 +179,29 @@ export class McpApiHelper {
|
||||
* @returns McpSession with sessionId and postUrl for sending messages
|
||||
*/
|
||||
async sseSetup(
|
||||
path: string,
|
||||
options?: {
|
||||
headers?: Record<string, string>;
|
||||
maxNotFoundRetries?: number;
|
||||
notFoundRetryDelayMs?: number;
|
||||
},
|
||||
): Promise<McpSession> {
|
||||
const maxNotFoundRetries = options?.maxNotFoundRetries ?? 5;
|
||||
const notFoundRetryDelayMs = options?.notFoundRetryDelayMs ?? 500;
|
||||
|
||||
for (let attempt = 0; attempt <= maxNotFoundRetries; attempt++) {
|
||||
try {
|
||||
return await this.attemptSseSetup(path, options);
|
||||
} catch (error) {
|
||||
if (!(error instanceof SseNotFoundError) || attempt === maxNotFoundRetries) throw error;
|
||||
await wait(notFoundRetryDelayMs);
|
||||
}
|
||||
}
|
||||
// unreachable: the catch above rethrows on the final attempt. Here to satisfy TS.
|
||||
throw new Error('SSE setup: retry loop exhausted');
|
||||
}
|
||||
|
||||
private async attemptSseSetup(
|
||||
path: string,
|
||||
options?: { headers?: Record<string, string> },
|
||||
): Promise<McpSession> {
|
||||
@@ -216,6 +242,14 @@ export class McpApiHelper {
|
||||
headers,
|
||||
},
|
||||
(res) => {
|
||||
if (res.statusCode === 404) {
|
||||
// Drain the response so the socket is released back to the pool across retries.
|
||||
res.resume();
|
||||
clearTimeout(timeout);
|
||||
reject(new SseNotFoundError(`SSE setup got 404 for ${path}`));
|
||||
return;
|
||||
}
|
||||
|
||||
let buffer = '';
|
||||
let resolved = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user