Skip to content

Some API errors return 500 for bad input or include the exception text in the response #1156

Open

Description

@Sahil-u07

Issue

What is the issue?

While working on #1152 I went through the other error paths in application/web/web_main.py. A few of them either return 500 for input the client got wrong, or copy the raw exception text into the response.

Bad input that ends up as a 500

  1. POST /rest/v1/cre_csv_import: a CSV that repeats a row makes the parser raise DuplicateLinkException ("Cannot link the same document twice, ..."), and the route turns that into abort(500, ...). The ValueError branch right below it already returns 400 for other bad CSV content.
  2. POST /rest/v1/completion: the handler calls .get("prompt") on whatever JSON arrives. A body like ["hi"] fails with 'list' object has no attribute 'get', and that comes back as a 500 that says it was an AI service error. A missing prompt is also passed straight to the model.
  3. GET /admin/imports/runs: limit and offset go through int() with no error handling, so ?limit=abc is a 500. A negative value goes straight into the SQL LIMIT/OFFSET, which Postgres rejects.

Exception text in the response

  1. GET /rest/v1/map_analysis: when the synchronous fallback fails, the route does abort(503, f"Gap analysis unavailable: {fallback_exc}"). Whatever the Neo4j or database driver put in the exception (host, port, sometimes credentials in a URL) goes to the client. This path is skipped on Heroku, so it affects local and self-hosted installs.
  2. POST /rest/v1/completion: any exception from generate_text comes back as {"error": "AI Service Error: <str(e)>"}. The chatbot page shows json.error directly in the chat window, so users see that text.

Expected Behaviour

  • 1 to 3 return 400 with a short message about what was wrong with the request.
  • 4 and 5 keep their status codes but return a fixed message, and log the exception on the server.

Actual Behaviour

From the Flask test client on current main:

cre_csv_import (same row twice)    -> 500  error during parsing of the incoming CSV, err:Cannot link the same document twice, document standard:1.1.1:ASVS is already linked to 123-456
completion json=["x"]              -> 500  {"error":"AI Service Error: 'list' object has no attribute 'get'"}
/admin/imports/runs?limit=abc      -> 500  ValueError: invalid literal for int() with base 10: 'abc'
map_analysis, fallback fails       -> 503  Gap analysis unavailable: neo4j://neo4j:s3cret@10.0.0.5:7687 refused
completion, generate_text raises   -> 500  {"error":"AI Service Error: connection to postgres://cre:hunter2@db:5432 failed"}

The last two use made-up exception messages to show that whatever the exception says is returned unchanged.

Steps to reproduce

  1. With CRE_ALLOW_IMPORT=1, upload a CSV whose header is CRE 0,standard|name,standard|id and that contains the row 123-456|A,ASVS,1.1.1 twice.
  2. With NO_LOGIN=1, POST /rest/v1/completion with the body ["x"].
  3. With NO_LOGIN=1 and CRE_ALLOW_IMPORT=1, GET /admin/imports/runs?limit=abc.
  4. With Redis and Neo4j both down and no DYNO/HEROKU set, GET /rest/v1/map_analysis?standard=a&standard=b.
  5. Make generate_text raise any exception, then call /rest/v1/completion with a valid prompt.

I'm planning to fix these in one PR with a separate commit for each, each with a test. fetch_job has the same exception-text problem, but that one is already handled in #1153.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions