Skip to content

fix: add bounded timeout and status handling to OperationService#37540

Open
ifer47 wants to merge 2 commits into
langgenius:mainfrom
ifer47:fix/operation-service-timeout
Open

fix: add bounded timeout and status handling to OperationService#37540
ifer47 wants to merge 2 commits into
langgenius:mainfrom
ifer47:fix/operation-service-timeout

Conversation

@ifer47

@ifer47 ifer47 commented Jun 16, 2026

Copy link
Copy Markdown

Summary

  • OperationService._send_request() used httpx.request without a timeout parameter, meaning billing/UTM requests could hang indefinitely on network issues
  • Called response.json() without checking the HTTP status code, so non-2xx/non-JSON responses surfaced as generic JSONDecodeError
  • Add httpx.Timeout(10.0, connect=3.0) matching the pattern used across Dify for billing/auth requests
  • Call response.raise_for_status() before JSON parsing so non-2xx responses raise httpx.HTTPStatusError with a clear message

Closes #37418

Test plan

  • Updated existing _send_request test to assert timeout parameter is passed
  • Added test_should_raise_on_non_2xx_response for raise_for_status behavior
  • Added test_should_pass_bounded_timeout for explicit timeout verification
  • All existing tests continue to pass

🤖 Generated with Claude Code Best

…ggenius#37418)

OperationService._send_request used httpx.request without a timeout
parameter and called response.json() without checking the HTTP status
code. A stalled billing endpoint could tie up a request worker
indefinitely, and non-2xx/non-JSON responses surfaced as generic
JSONDecodeErrors.

- Add httpx.Timeout(10.0, connect=3.0) matching the pattern used across
  Dify for billing/auth requests
- Call response.raise_for_status() before JSON parsing so non-2xx
  responses raise httpx.HTTPStatusError with a clear message instead of
  leaking through as JSON parse failures

Co-Authored-By: zhipu/glm-5 <zai-org@claude-code-best.win>
@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Jun 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-06-16 19:23:29.826055817 +0000
+++ /tmp/pyrefly_pr.txt	2026-06-16 19:23:15.160945720 +0000
@@ -2883,48 +2883,44 @@
    --> tests/unit_tests/core/app/apps/advanced_chat/test_generate_task_pipeline_core.py:652:52
 ERROR `(**kwargs: Unknown) -> Literal['failed']` is not assignable to attribute `workflow_node_finish_to_stream_response` with type `(self: WorkflowResponseConverter, *, event: QueueNodeExceptionEvent | QueueNodeFailedEvent | QueueNodeSucceededEvent, task_id: str) -> NodeFinishStreamResponse | None` [bad-assignment]
    --> tests/unit_tests/core/app/apps/advanced_chat/test_generate_task_pipeline_core.py:674:89
-ERROR Object of class `NoneType` has no attribute `prompt_messages` [missing-attribute]
-   --> tests/unit_tests/core/app/apps/agent_app/test_app_runner.py:168:23
 ERROR Object of class `NoneType` has no attribute `message` [missing-attribute]
-   --> tests/unit_tests/core/app/apps/agent_app/test_app_runner.py:186:12
+   --> tests/unit_tests/core/app/apps/agent_app/test_app_runner.py:176:12
 ERROR Object of class `NoneType` has no attribute `model` [missing-attribute]
-   --> tests/unit_tests/core/app/apps/agent_app/test_app_runner.py:187:12
+   --> tests/unit_tests/core/app/apps/agent_app/test_app_runner.py:177:12
 ERROR Object of class `NoneType` has no attribute `message` [missing-attribute]
   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:65:12
-ERROR Object of class `NoneType` has no attribute `prompt_messages` [missing-attribute]
-  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:70:23
 ERROR Argument `SimpleNamespace` is not assignable to parameter `application_generate_entity` with type `AgentAppGenerateEntity` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:82:41
+  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:75:41
 ERROR Argument `SimpleNamespace` is not assignable to parameter `app_model` with type `App` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:83:23
+  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:76:23
 ERROR Argument `SimpleNamespace` is not assignable to parameter `message` with type `Message` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:84:21
+  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:77:21
 ERROR Argument `_FakeQueueManager` is not assignable to parameter `queue_manager` with type `AppQueueManager` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:85:27
+  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:78:27
 ERROR Argument `SimpleNamespace` is not assignable to parameter `application_generate_entity` with type `AgentAppGenerateEntity` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:98:41
+  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:91:41
 ERROR Argument `SimpleNamespace` is not assignable to parameter `app_model` with type `App` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:99:23
+  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:92:23
 ERROR Argument `SimpleNamespace` is not assignable to parameter `message` with type `Message` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:100:21
+  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:93:21
 ERROR Argument `_FakeQueueManager` is not assignable to parameter `queue_manager` with type `AppQueueManager` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:101:27
+  --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:94:27
 ERROR Argument `SimpleNamespace` is not assignable to parameter `application_generate_entity` with type `AgentAppGenerateEntity` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:114:41
+   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:107:41
 ERROR Argument `SimpleNamespace` is not assignable to parameter `app_model` with type `App` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:115:23
+   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:108:23
 ERROR Argument `SimpleNamespace` is not assignable to parameter `message` with type `Message` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:116:21
+   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:109:21
 ERROR Argument `_FakeQueueManager` is not assignable to parameter `queue_manager` with type `AppQueueManager` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:117:27
+   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:110:27
 ERROR Argument `SimpleNamespace` is not assignable to parameter `application_generate_entity` with type `AgentAppGenerateEntity` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:131:41
+   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:123:41
 ERROR Argument `SimpleNamespace` is not assignable to parameter `app_model` with type `App` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:132:23
+   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:124:23
 ERROR Argument `SimpleNamespace` is not assignable to parameter `message` with type `Message` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:133:21
+   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:125:21
 ERROR Argument `_FakeQueueManager` is not assignable to parameter `queue_manager` with type `AppQueueManager` in function `core.app.apps.agent_app.app_generator.AgentAppGenerator._run_input_guards` [bad-argument-type]
-   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:134:27
+   --> tests/unit_tests/core/app/apps/agent_app/test_input_guards.py:126:27
 ERROR Object of class `LayerConfig` has no attribute `plugin_id`
 ERROR Object of class `LayerConfig` has no attribute `model_provider`
 ERROR Object of class `LayerConfig` has no attribute `conversation_id`
@@ -6496,7 +6492,7 @@
 ERROR Argument `frozenset[str]` is not assignable to parameter `scopes` with type `frozenset[Scope]` in function `libs.oauth_bearer.AuthContext.__init__` [bad-argument-type]
   --> tests/unit_tests/services/test_oauth_device_flow.py:38:16
 ERROR Argument `dict[str, Any]` is not assignable to parameter `utm_info` with type `UtmInfo` in function `services.operation_service.OperationService.record_utm` [bad-argument-type]
-   --> tests/unit_tests/services/test_operation_service.py:117:57
+   --> tests/unit_tests/services/test_operation_service.py:123:57
 ERROR Argument `Literal['']` is not assignable to parameter `plan` with type `CloudPlan` in function `RagPipelineTaskProxyTestDataFactory.create_mock_features` [bad-argument-type]
    --> tests/unit_tests/services/test_rag_pipeline_task_proxy.py:409:109
 ERROR Argument `None` is not assignable to parameter `plan` with type `CloudPlan` in function `RagPipelineTaskProxyTestDataFactory.create_mock_features` [bad-argument-type]

@github-actions

Copy link
Copy Markdown
Contributor

Pyrefly Type Coverage

Metric Base PR Delta
Type coverage 48.59% 48.59% +0.00%
Strict coverage 48.10% 48.10% +0.00%
Typed symbols 27,995 27,998 +3
Untyped symbols 29,922 29,924 +2
Modules 2892 2892 0

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

Labels

size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OperationService billing requests have no timeout or status handling

1 participant