{"record":{"id":"3cd681fdc4d3ab79","repo":"FlowiseAI/Flowise","slug":"failed-to-action-status-code-response-statu-3cd681","errorCode":null,"errorMessage":"Failed to ${action}. Status code: ${response.status}. Error: ${errorMessage}","messagePattern":"Failed to (.+?)\\. Status code: (.+?)\\. Error: (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/documentloaders/Spider/SpiderApp.ts","lineNumber":110,"sourceCode":"        return { success: false, error: 'Internal server error.' }\n    }\n\n    private prepareHeaders(idempotencyKey?: string): AxiosRequestHeaders {\n        return {\n            'Content-Type': 'application/json',\n            Authorization: `Bearer ${this.apiKey}`,\n            ...(idempotencyKey ? { 'x-idempotency-key': idempotencyKey } : {})\n        } as AxiosRequestHeaders & { 'x-idempotency-key'?: string }\n    }\n\n    private postRequest(url: string, data: Params, headers: AxiosRequestHeaders): Promise<AxiosResponse> {\n        return secureAxiosRequest({ method: 'POST', url: `${this.apiUrl}/${url}`, data, headers })\n    }\n\n    private handleError(response: AxiosResponse, action: string): void {\n        if ([402, 408, 409, 500].includes(response.status)) {\n            const errorMessage: string = response.data.error || 'Unknown error occurred'\n            throw new Error(`Failed to ${action}. Status code: ${response.status}. Error: ${errorMessage}`)\n        } else {\n            throw new Error(`Unexpected error occurred while trying to ${action}. Status code: ${response.status}`)\n        }\n    }\n}\n\nexport default SpiderApp\n","sourceCodeStart":92,"sourceCodeEnd":118,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/documentloaders/Spider/SpiderApp.ts#L92-L118","documentation":"SpiderApp.handleError for HTTP statuses 402, 408, 409, 500. These are the 'known' Spider failure statuses; the thrown message interpolates the action ('scrape URL' / 'start crawl job'), the status code, and the upstream errorMessage from response.data.error.","triggerScenarios":"Spider API responds 402 (payment/quota), 408 (request timeout), 409 (conflict — e.g. duplicate crawl), or 500 (server error). handleError is called from scrapeUrl/crawlUrl when response.status !== 200.","commonSituations":"Free plan quota hit (402), slow target causing Spider-side timeout (408), retrying an idempotent crawl with the same key (409), or a Spider platform incident (500).","solutions":["402: upgrade the Spider plan or wait for quota reset; check the dashboard.","408/500: retry with exponential backoff; check status.spider.cloud.","409: use a different idempotency key or fetch the existing job instead of resubmitting.","Parse response.data.error to surface the exact upstream reason to the end user.","Log the status code separately so alerting can distinguish transient from permanent."],"exampleFix":"// before\nconst errorMessage: string = response.data.error || 'Unknown error occurred'\nthrow new Error(`Failed to ${action}. Status code: ${response.status}. Error: ${errorMessage}`)\n\n// after\nconst errorMessage: string = response?.data?.error || 'Unknown error occurred'\nconst err = new Error(`Failed to ${action}. Status code: ${response.status}. Error: ${errorMessage}`)\n;(err as any).status = response.status\nthrow err","handlingStrategy":"retry","validationCode":"import axios from 'axios'\nfunction isRetryableSpiderStatus(s: number): boolean {\n    return [402, 408, 409, 429, 500, 502, 503, 504].includes(s)\n}","typeGuard":"function isSpiderKnownFailure(status: number): boolean {\n    return [402, 408, 409, 500].includes(status)\n}","tryCatchPattern":"for (let attempt = 0; attempt < 3; attempt++) {\n    try {\n        return await app.crawlUrl(url, params)\n    } catch (e: any) {\n        const m = e.message.match(/Status code: (\\d+)/)\n        const status = m ? Number(m[1]) : 0\n        if (status === 409) return await pollExistingJob()\n        if (isRetryableSpiderStatus(status) && attempt < 2) { await sleep(2 ** attempt * 500); continue }\n        throw e\n    }\n}","preventionTips":["Parse the embedded status code to drive retry/escalation logic.","402 is permanent for the current plan — surface a clear upgrade prompt.","409 indicates an existing job — fetch it instead of resubmitting.","Alert on repeated 500s as a Spider platform incident signal."],"tags":["spider","api","http-status","quota"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}