Skip to content

fix(serper): add request timeout and credential guard#3468

Open
Harsh23Kashyap wants to merge 2 commits into
langgenius:mainfrom
Harsh23Kashyap:fix/serper-requests-timeouts-and-credential-guards
Open

fix(serper): add request timeout and credential guard#3468
Harsh23Kashyap wants to merge 2 commits into
langgenius:mainfrom
Harsh23Kashyap:fix/serper-requests-timeouts-and-credential-guards

Conversation

@Harsh23Kashyap

Copy link
Copy Markdown
Contributor

Summary

Mirrors the same two-bug reliability pattern that PR #3456 (already MERGED on 2026-07-20, tools/google) and PR #3466 (tools/searchapi, opened today) just fixed, applied to tools/serper.

Refs #3465 (umbrella tracker — also includes tools/{searchapi, tianditu}).

Changes

  • requests.get(...) now passes timeout=10. 10 s is well above the upstream Serper.dev p99 and well below the framework-level 120 s ceiling.
  • self.runtime.credentials["serperapi_api_key"] is replaced with an early guard that yields "Serper.dev API key is required." and returns; the value is read via .get(). No more KeyError on a missing or empty key.
  • Wraps the HTTP call in try / except requests.exceptions.RequestException so a timeout, connection reset, DNS failure, or 5xx surfaces as a friendly message instead of a stack trace.
  • New tools/serper/tests/test_serper.py with 6 in-process test cases (no pytest or dify_plugin runtime needed — uses only unittest.mock + minimal sys-modules stubs).
  • manifest.yaml PATCH bump 0.0.7 -> 0.0.8.

serper_search.py does not take user-supplied hl / gl (the values are hardcoded to "us" / "en"), so the third bug from PR #3456 (invoke fall-through on invalid hl / gl) does not apply.

Change Type

  • Documentation / non-plugin change
  • Non-LLM plugin only (LLM and multimodal model plugin)

LLM Plugin Checklist

Not applicable — this is a tool plugin.

Version

  • manifest.yaml is 0.0.8.
  • requests>=2.34.2 is already declared and locked.

Testing

  • python3 -m pytest tests/test_serper.py -v -> 6 passed.
  • uv run --frozen ruff check . -> All checks passed.
  • python3 -m py_compile tools/serper_search.py tests/test_serper.py -> OK.

Risks

  • None for behavior on the healthy path — successful 200 responses remain byte-identical.

Out of scope (deliberate)

  • No model-provider plugin work; only tools/*.

References

Mirrors the same three-bug reliability pattern from PR langgenius#3456
(tools/google) and PR langgenius#3466 (tools/searchapi):

- requests.get had no timeout= argument; stalled hosts blocked until
  the framework-level 120s ceiling. Add timeout=10.
- self.runtime.credentials["serperapi_api_key"] raised KeyError when
  the key was absent or empty. Replace with an early guard that yields
  a friendly error message and returns; use .get() for the value lookup.
- Wrap the HTTP call in try/except requests.RequestException so a
  timeout, connection reset, DNS failure, or 5xx surfaces as a friendly
  message instead of a stack trace.

serper has no user-supplied hl / gl (the values are hardcoded to "us" /
"en"), so the invoke fall-through bug from PR langgenius#3456 does not apply.

No public API change; successful 200-path responses are byte-identical.

Adds tools/serper/tests/test_serper.py with 6 in-process test cases.
Bumps manifest 0.0.7 -> 0.0.8.

Refs langgenius#3465
Refs langgenius#3456

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds reliability safeguards to the Serper tool.

Changes:

  • Adds credential validation and a 10-second request timeout.
  • Converts request failures into user-facing messages.
  • Adds regression tests and bumps the plugin version.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
tools/serper/tools/serper_search.py Adds credential and request-error handling.
tools/serper/tests/test_serper.py Tests credentials, timeout, failures, and success.
tools/serper/tests/__init__.py Initializes the tests package.
tools/serper/manifest.yaml Bumps version to 0.0.8.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +38 to +42
except requests.exceptions.RequestException as exc:
yield self.create_text_message(
f"An error occurred while invoking the tool: {exc}."
)
return
Comment thread tools/serper/tests/test_serper.py Outdated
@@ -0,0 +1,212 @@
"""In-process tests for tools/serper (no pytest required).
Comment thread tools/serper/tests/test_serper.py Outdated
Comment on lines +12 to +14
They use only Python stdlib (`unittest.mock`) and tiny in-test stubs for
`requests`, `dify_plugin`, and `pydantic` so they can run in environments
where the plugin dependencies are not pre-installed.
Drop the misleading no-pytest-required wording and remove pydantic from
the stub dependency list. The test file uses bare test_* functions with
assert and is intended to run under pytest.

Refs langgenius#3465
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants