mirror of
https://git.mirrors.martin98.com/https://github.com/mendableai/firecrawl
synced 2025-08-12 20:29:01 +08:00
feat(v1/map): timeout
This commit is contained in:
parent
173028295b
commit
57e98e83d7
42
apps/api/src/__tests__/snips/map.test.ts
Normal file
42
apps/api/src/__tests__/snips/map.test.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import request from "supertest";
|
||||||
|
import { configDotenv } from "dotenv";
|
||||||
|
import { MapRequestInput } from "../../controllers/v1/types";
|
||||||
|
|
||||||
|
configDotenv();
|
||||||
|
const TEST_URL = "http://127.0.0.1:3002";
|
||||||
|
|
||||||
|
async function map(body: MapRequestInput) {
|
||||||
|
return await request(TEST_URL)
|
||||||
|
.post("/v1/map")
|
||||||
|
.set("Authorization", `Bearer ${process.env.TEST_API_KEY}`)
|
||||||
|
.set("Content-Type", "application/json")
|
||||||
|
.send(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectMapToSucceed(response: Awaited<ReturnType<typeof map>>) {
|
||||||
|
expect(response.statusCode).toBe(200);
|
||||||
|
expect(response.body.success).toBe(true);
|
||||||
|
expect(Array.isArray(response.body.links)).toBe(true);
|
||||||
|
expect(response.body.links.length).toBeGreaterThan(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Map tests", () => {
|
||||||
|
it("basic map succeeds", async () => {
|
||||||
|
const response = await map({
|
||||||
|
url: "http://firecrawl.dev",
|
||||||
|
});
|
||||||
|
|
||||||
|
expectMapToSucceed(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("times out properly", async () => {
|
||||||
|
const response = await map({
|
||||||
|
url: "http://firecrawl.dev",
|
||||||
|
timeout: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(408);
|
||||||
|
expect(response.body.success).toBe(false);
|
||||||
|
expect(response.body.error).toBe("Request timed out");
|
||||||
|
});
|
||||||
|
});
|
@ -276,17 +276,34 @@ export async function mapController(
|
|||||||
) {
|
) {
|
||||||
req.body = mapRequestSchema.parse(req.body);
|
req.body = mapRequestSchema.parse(req.body);
|
||||||
|
|
||||||
const result = await getMapResults({
|
let result: Awaited<ReturnType<typeof getMapResults>>;
|
||||||
url: req.body.url,
|
try {
|
||||||
search: req.body.search,
|
result = await Promise.race([
|
||||||
limit: req.body.limit,
|
getMapResults({
|
||||||
ignoreSitemap: req.body.ignoreSitemap,
|
url: req.body.url,
|
||||||
includeSubdomains: req.body.includeSubdomains,
|
search: req.body.search,
|
||||||
crawlerOptions: req.body,
|
limit: req.body.limit,
|
||||||
origin: req.body.origin,
|
ignoreSitemap: req.body.ignoreSitemap,
|
||||||
teamId: req.auth.team_id,
|
includeSubdomains: req.body.includeSubdomains,
|
||||||
plan: req.auth.plan,
|
crawlerOptions: req.body,
|
||||||
});
|
origin: req.body.origin,
|
||||||
|
teamId: req.auth.team_id,
|
||||||
|
plan: req.auth.plan,
|
||||||
|
}),
|
||||||
|
...(req.body.timeout !== undefined ? [
|
||||||
|
new Promise((resolve, reject) => setTimeout(() => reject("timeout"), req.body.timeout))
|
||||||
|
] : []),
|
||||||
|
]) as any;
|
||||||
|
} catch (error) {
|
||||||
|
if (error === "timeout") {
|
||||||
|
return res.status(408).json({
|
||||||
|
success: false,
|
||||||
|
error: "Request timed out",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Bill the team
|
// Bill the team
|
||||||
billTeam(req.auth.team_id, req.acuc?.sub_id, 1).catch((error) => {
|
billTeam(req.auth.team_id, req.acuc?.sub_id, 1).catch((error) => {
|
||||||
|
@ -429,6 +429,7 @@ export const mapRequestSchema = crawlerOptions
|
|||||||
ignoreSitemap: z.boolean().default(false),
|
ignoreSitemap: z.boolean().default(false),
|
||||||
sitemapOnly: z.boolean().default(false),
|
sitemapOnly: z.boolean().default(false),
|
||||||
limit: z.number().min(1).max(5000).default(5000),
|
limit: z.number().min(1).max(5000).default(5000),
|
||||||
|
timeout: z.number().positive().finite().optional(),
|
||||||
})
|
})
|
||||||
.strict(strictMessage);
|
.strict(strictMessage);
|
||||||
|
|
||||||
@ -438,6 +439,7 @@ export const mapRequestSchema = crawlerOptions
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
export type MapRequest = z.infer<typeof mapRequestSchema>;
|
export type MapRequest = z.infer<typeof mapRequestSchema>;
|
||||||
|
export type MapRequestInput = z.input<typeof mapRequestSchema>;
|
||||||
|
|
||||||
export type Document = {
|
export type Document = {
|
||||||
title?: string;
|
title?: string;
|
||||||
|
@ -235,6 +235,7 @@ export interface MapParams {
|
|||||||
includeSubdomains?: boolean;
|
includeSubdomains?: boolean;
|
||||||
sitemapOnly?: boolean;
|
sitemapOnly?: boolean;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
|
timeout?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user