fix: address codex review findings on web seam

- search providers (exa/perplexity/deepseek): map the parsed response
  INSIDE the parse try, so a well-formed body of the wrong shape surfaces
  as WEB_PROVIDER_ERROR instead of escaping as a raw TypeError; a WebError
  the mapper throws on purpose is re-thrown untouched
- web-fetch-local: validate numeric limits at plugin construction (positive
  finite caps; non-negative integer maxRedirects) rather than constructing a
  provider with nonsensical values
- web-fetch-local: enforce the redirect budget BEFORE resolving each hop, so
  maxRedirects:N follows exactly N redirects and an over-limit hop reports
  "exceeded the maximum" rather than misdiagnosing a cross-origin block
- drop the stale dsh-tool-web/search and /fetch path aliases (the package no
  longer declares those subpath exports)
- strip trailing EOF blank lines flagged by git diff --check

Each fix carries a regression test.
This commit is contained in:
Dudu-0223
2026-06-29 17:23:11 +08:00
parent b92a3c531a
commit 8395722db5
14 changed files with 157 additions and 21 deletions
@@ -126,14 +126,14 @@ export class PerplexitySearchProvider implements WebSearchProvider {
throw new WebError(message, 'WEB_PROVIDER_ERROR')
}
let payload: PerplexityResponse
try {
payload = await response.json() as PerplexityResponse
const payload = await response.json() as PerplexityResponse
return mapPerplexityResponse(request.query, payload)
} catch (error: unknown) {
if (isAbortError(error)) throw new WebError('Perplexity search aborted', 'WEB_ABORTED', { cause: error })
throw new WebError(`Perplexity returned an unparseable response body: ${String(error)}`, 'WEB_PROVIDER_ERROR', { cause: error })
if (error instanceof WebError) throw error
throw new WebError(`Perplexity returned an unprocessable response body: ${String(error)}`, 'WEB_PROVIDER_ERROR', { cause: error })
}
return mapPerplexityResponse(request.query, payload)
}
}