mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-22 07:02:16 +03:00
Merge pull request #10919 from diegosouzapw/fix/10849-search-provider-400
fix(api): POST /v1/search names unknown providers instead of opaque 400 (#10849)
This commit is contained in:
@@ -19,7 +19,11 @@ import * as log from "@/sse/utils/logger";
|
||||
import { toJsonErrorPayload } from "@/shared/utils/upstreamError";
|
||||
import { enforceApiKeyPolicy } from "@/shared/utils/apiKeyPolicy";
|
||||
import { v1SearchSchema } from "@/shared/validation/schemas";
|
||||
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
|
||||
import {
|
||||
formatValidationMessage,
|
||||
isValidationFailure,
|
||||
validateBody,
|
||||
} from "@/shared/validation/helpers";
|
||||
import { recordCost } from "@/domain/costRules";
|
||||
import {
|
||||
computeCacheKey,
|
||||
@@ -120,7 +124,7 @@ async function postHandler(request: Request, context: unknown) {
|
||||
|
||||
const validation = validateBody(v1SearchSchema, rawBody);
|
||||
if (isValidationFailure(validation)) {
|
||||
return errorResponse(HTTP_STATUS.BAD_REQUEST, validation.error.message);
|
||||
return errorResponse(HTTP_STATUS.BAD_REQUEST, formatValidationMessage(validation.error));
|
||||
}
|
||||
const body = validation.data;
|
||||
|
||||
|
||||
@@ -56,6 +56,19 @@ export function isValidationFailure<TData>(
|
||||
return validation.success === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a human-readable 400 message from a validation failure, naming the
|
||||
* first offending field instead of the generic "Invalid request" (#10849).
|
||||
* Intended for routes that reply with a single message string (e.g.
|
||||
* `errorResponse()`) rather than the full `{ message, details }` envelope
|
||||
* returned by `validatedJsonBody()`.
|
||||
*/
|
||||
export function formatValidationMessage(error: ValidationErrorPayload): string {
|
||||
const [first] = error.details;
|
||||
if (!first) return error.message;
|
||||
return first.field ? `${first.field}: ${first.message}` : first.message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of attempting to parse and validate a JSON body against a Zod schema.
|
||||
*
|
||||
|
||||
@@ -568,27 +568,16 @@ export const v1SearchSchema = z
|
||||
.trim()
|
||||
.min(1, "Query is required")
|
||||
.max(500, "Query must be 500 characters or fewer"),
|
||||
provider: z
|
||||
.enum([
|
||||
"serper-search",
|
||||
"brave-search",
|
||||
"perplexity-search",
|
||||
"exa-search",
|
||||
"tavily-search",
|
||||
"firecrawl",
|
||||
"google-pse-search",
|
||||
"linkup-search",
|
||||
"ollama-search",
|
||||
"searchapi-search",
|
||||
"youcom-search",
|
||||
"searxng-search",
|
||||
"zai-search",
|
||||
"jina-search",
|
||||
"jina-ai",
|
||||
"jina",
|
||||
"duckduckgo-free",
|
||||
])
|
||||
.optional(),
|
||||
// Not a z.enum: the runtime catalog (SEARCH_PROVIDERS + SEARCH_PROVIDER_ALIASES in
|
||||
// open-sse/config/searchRegistry.ts) is the source of truth via resolveSearchProvider(),
|
||||
// which already returns a named "Unknown search provider: <id>" error for bad ids (see
|
||||
// src/app/api/v1/search/route.ts). A hard-coded enum here would 400 before that check
|
||||
// ever runs, hiding the informative message behind a generic Zod failure (#10849).
|
||||
// Known catalog ids as of this writing: serper-search, brave-search, perplexity-search,
|
||||
// exa-search, tavily-search, firecrawl, google-pse-search, linkup-search, ollama-search,
|
||||
// searchapi-search, youcom-search, searxng-search, zai-search, jina-search, jina-ai,
|
||||
// jina, duckduckgo-free (plus short aliases resolved by SEARCH_PROVIDER_ALIASES).
|
||||
provider: z.string().min(1).optional(),
|
||||
max_results: z.coerce.number().int().min(1).max(100).default(5),
|
||||
search_type: z.enum(["web", "news"]).default("web"),
|
||||
offset: z.coerce.number().int().min(0).default(0),
|
||||
|
||||
Reference in New Issue
Block a user