Skip to content

fix: preserve HTTPException status in update_docling_preset (#1586)#1814

Closed
hunterxtang wants to merge 3 commits into
langflow-ai:mainfrom
hunterxtang:fix/1586-docling-preset-status
Closed

fix: preserve HTTPException status in update_docling_preset (#1586)#1814
hunterxtang wants to merge 3 commits into
langflow-ai:mainfrom
hunterxtang:fix/1586-docling-preset-status

Conversation

@hunterxtang

@hunterxtang hunterxtang commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Fixes #1586

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling for the docling-preset endpoint: client-side issues (such as invalid preset values) now preserve the original HTTP status codes and messages instead of being converted into a generic server error.
  • Tests
    • Added a unit test to confirm invalid preset requests return a 400 response with the expected error detail.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The deprecated /settings/docling-preset endpoint now re-raises caught HTTPException instances in update_docling_preset, preserving original HTTP status codes; other exceptions are logged and result in a generic 500 HTTPException. A unit test asserting a 400 for an invalid preset was added.

Changes

HTTP Exception Handling Fix

Layer / File(s) Summary
Preserve HTTPException and add unit test
src/api/settings/endpoints.py, tests/unit/api/test_settings_endpoints.py
update_docling_preset now explicitly catches and re-raises fastapi.HTTPException before a generic except Exception that logs and raises a 500; a pytest-asyncio unit test asserts a 400 response for an invalid preset input.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main fix: preserving HTTPException status in the update_docling_preset function, which is the core change in this pull request.
Linked Issues check ✅ Passed The pull request implements all key objectives from issue #1586: adds specific HTTPException handler to preserve 400 status codes, removes raw exception text from client responses, retains it in logs, maintains exception chaining, and includes regression test.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the HTTPException handling in update_docling_preset and adding regression test coverage; no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added community backend 🔷 Issues related to backend services (OpenSearch, Langflow, APIs) bug 🔴 Something isn't working. labels Jun 9, 2026
@hunterxtang hunterxtang force-pushed the fix/1586-docling-preset-status branch from e3de2b3 to cd3713f Compare June 9, 2026 16:47
@github-actions github-actions Bot added bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jun 9, 2026
@Wallgau Wallgau requested a review from mpawlow June 11, 2026 17:49

@Vchen7629 Vchen7629 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@mpawlow mpawlow left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Good job @hunterxtang

Code Review 1

  • See PR comments: (1a), (1b) for relative easy tweaks / fixes

Comment thread src/api/settings/endpoints.py Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

(1a) [Normal] Raw exception message leaked in 500 response detail string

Problem

  • Embedding str(e) in API response bodies can expose internal implementation details (file paths, library internals, config values, stack-frame fragments) to any caller — a recognized security anti-pattern (OWASP A05:2021 — Security Misconfiguration; CWE-209: Information Exposure Through an Error Message).
  • The error is already fully captured server-side via logger.error("Failed to update docling settings", error=str(e)), so no diagnostic value is lost by removing str(e) from the detail.
  • Note: This was explicitly called out in the linked issue's own proposed fix (bug: HTTPException(400) swallowed as 500 in update_docling_preset #1586):
    -            status_code=500, detail=f"Failed to update docling settings: {str(e)}"
    +            status_code=500, detail="Failed to update docling settings"
    The PR applied the except HTTPException: raise part of that fix but did not carry forward this secondary hardening.

Code References

  • src/api/settings/endpoints.py:1630 — primary (this PR's scope)

Potential Solution

Strip the raw exception from the client-facing detail string:

except Exception as e:
    logger.error("Failed to update docling settings", error=str(e))
    raise HTTPException(
        status_code=500, detail="Failed to update docling settings"
    ) from e


except HTTPException:
# Preserve intended HTTP status codes (e.g. 400 for an invalid preset)
raise

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

(1b) [Minor] No regression test added to guard the fixed behavior

Problem

  • The PR fixes a bug where an invalid preset silently produced a 500 instead of the intended 400, but no test was added to assert the corrected behavior.
  • Without a test, any future refactor that reorders or widens the except chain could silently reproduce the original bug with no CI signal.
  • A unit test calling update_docling_preset directly with an invalid preset body and asserting status_code=400 would require no infra and would be straightforward to add.

Code References

  • src/api/settings/endpoints.py:1590–1594 — the raise HTTPException(status_code=400, ...) path the fix protects
  • tests/unit/test_docling_service.py — closest existing test file; an additional test belongs here or in a new test_settings_endpoints.py

Potential Solution

import pytest
from fastapi import HTTPException
from unittest.mock import AsyncMock

@pytest.mark.asyncio
async def test_update_docling_preset_invalid_preset_returns_400():
    from api.settings.endpoints import update_docling_preset
    from api.settings.models import DoclingPresetBody

    body = DoclingPresetBody(preset="nonexistent_preset")

    with pytest.raises(HTTPException) as exc_info:
        await update_docling_preset(body=body, session_manager=AsyncMock(), user=AsyncMock())

    assert exc_info.value.status_code == 400

@github-actions github-actions Bot added tests bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jun 12, 2026
@hunterxtang

hunterxtang commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

1a) Removed str(e) from the client-facing detail so the 500 no longer leaks internal exception text; kept str(e) in the logger.error call for server-side diagnostics, and preserved the from e chaining. The detail is now a static "Failed to update docling settings".

1b) Added test_update_docling_preset_invalid_preset_returns_400 in tests/unit/api/test_settings_endpoints.py. It sends an invalid preset and asserts the call raises HTTPException with status_code == 400. To confirm it actually guards the fix, I verified it fails (returns 500) when the except HTTPException: raise block is removed, then restored the block. Any future refactor that reorders or widens the except chain will trip CI, which was the concern here.

@mpawlow

mpawlow commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Thanks @hunterxtang

  • Changes look good 👍
  • Running remaining workflows...
    • Waiting to see if E2E Tests / Integration Tests pass...

@mpawlow

mpawlow commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Error: OPENAI_API_KEY is not set

  • Integration tests are failing
  • I think this is a workflow error related to this being a forked Pull Request
  • Following up with the rest of the team on this...

@mpawlow

mpawlow commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Error: 6-12T17:26:14,233][ERROR][o.o.s.a.BackendRegistry ] [504d3485a6c9] OpenSearch Security not initialized. (you may need to run securityadmin)

Error: OPENAI_API_KEY is not set

  • ❌ Suspicion: Forked PR causing the E2E tests and integration tests to fail

CC @Wallgau @lucaseduoli

@mpawlow mpawlow left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review 2

  • ✅ Approved / LGTM 🚀
  • ⚠️ Need to resolve E2E / Integration test failures in the workflow before merge (potential infrastructure problems)

@github-actions github-actions Bot added bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jun 15, 2026
@github-actions github-actions Bot added the bug 🔴 Something isn't working. label Jun 15, 2026

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
src/api/settings/endpoints.py (1)

1085-1120: ⚖️ Poor tradeoff

Unrelated refactoring mixed with the docling preset fix.

The PR objectives (issue #1586) describe only the HTTPException status preservation fix in update_docling_preset (lines 1600-1605). However, this diff also includes an unrelated refactoring of OpenSearch client creation in the onboarding function (lines 1085-1120). The AI summary mentions this refactoring but the PR objectives and issue description do not.

Mixing unrelated changes in a single PR reduces reviewability and makes rollback more difficult if one change needs to be reverted independently. Consider moving the OpenSearch client refactoring to a separate PR.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/settings/endpoints.py` around lines 1085 - 1120, Remove the
OpenSearch client creation refactoring from this PR as it is unrelated to the
main objective of fixing HTTPException status preservation in the
update_docling_preset function. The refactoring of admin_username determination
and the associated logging in the onboarding function (lines 1085-1120) should
be moved to a separate pull request to maintain focus on the issue `#1586` fix and
improve code review clarity.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/api/settings/endpoints.py`:
- Around line 1085-1120: Remove the OpenSearch client creation refactoring from
this PR as it is unrelated to the main objective of fixing HTTPException status
preservation in the update_docling_preset function. The refactoring of
admin_username determination and the associated logging in the onboarding
function (lines 1085-1120) should be moved to a separate pull request to
maintain focus on the issue `#1586` fix and improve code review clarity.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 381ed3c7-f2f6-4781-84df-ce38f9d3ee75

📥 Commits

Reviewing files that changed from the base of the PR and between 6b457b8 and c2b0984.

📒 Files selected for processing (1)
  • src/api/settings/endpoints.py

@mpawlow

mpawlow commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

🚧 Re-running the GitHub workflow to see if the E2E / Integration test failures are resolved

@mpawlow

mpawlow commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Still failing...

@Wallgau @lucaseduoli

  • Question: Should we just forcibly merge this forked PR in the interim OR attempt to resolve the underlying problem of forked PR access to the OpenAI credentials within the GitHub Action context?

@Wallgau

Wallgau commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Still failing...

@Wallgau @lucaseduoli

  • Question: Should we just forcibly merge this forked PR in the interim OR attempt to resolve the underlying problem of forked PR access to the OpenAI credentials within the GitHub Action context?

we should probably create a new branch from the release one and apply changes there, @lucaseduoli ?

@mpawlow

mpawlow commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Anyone with collaborator access to this repository can use these secrets and variables for actions. They are not passed to workflows that are triggered by a pull request from a fork.

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

Labels

backend 🔷 Issues related to backend services (OpenSearch, Langflow, APIs) bug 🔴 Something isn't working. community tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: HTTPException(400) swallowed as 500 in update_docling_preset

4 participants