RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /First Local Chatbot
  6. /Ch. 11
First Local Chatbot

11. Error Handling

Chapter 11 of 15 · 20 min
KEY INSIGHT

Handle errors at every layer: Ollama API errors, HTTP errors, SSE parsing errors, and session errors. Silent failures are the hardest to debug.

Four error categories will surface during development:

1. Ollama connection errors. httpx.ConnectError when Ollama is not running. Handle by returning a structured error response:

@app.post("/chat")
async def chat(...):
    try:
        # ... streaming logic
    except httpx.ConnectError:
        return JSONResponse({"error": "Ollama is not running. Start it with: ollama serve"}, status_code=503)
    except httpx.TimeoutException:
        return JSONResponse({"error": "Ollama timed out. The model may be slow or overloaded."}, status_code=504)

2. Model not found. Ollama returns a JSON error body. Parse it from the SSE stream:

for line in resp.iter_lines():
    if line:
        try:
            data = json.loads(line)
            if data.get("error"):
                yield f"data: {json.dumps({'error': data['error']})}\n\n"
                return
        except json.JSONDecodeError:
            pass

3. SSE format errors. The frontend will receive malformed chunks if the backend sends data without the data: prefix or the double newline. Add a simple validation:

if (!line.startsWith("data: ")) continue;

4. Session not found. If a session ID does not exist, return an empty history rather than a 404:

@app.get("/session/{session_id}")
def get_session(session_id: str):
    return {"history": sessions.get(session_id, [])}

Log all errors to stdout with timestamps for debugging.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

EXERCISE

Introduce a deliberate bug (wrong port) and verify that the frontend shows a meaningful error message instead of a blank screen.

← Chapter 10
Multiple Model Selection
Chapter 12 →
UI Polish