from flask import jsonify def error_response(code, message, status=400): """ Returns a structured JSON error response. Every Flask route in this codebase uses this helper — plain-text or stack-trace error bodies are a build failure per CLAUDE.md §18. Data flow: code + message + status → JSON body { error: true, code, message } → (body, status) tuple returned, suitable as a Flask route return value """ return jsonify({'error': True, 'code': code, 'message': message}), status # User-facing failure messages for the four JobProgress terminal states # plus proxy errors — surfaced in scrape_runs.error_log and shown verbatim # in the dashboard's failed-state UI (CLAUDE.md "Error Handling" section). FAILURE_MESSAGES = { 'scrape_blocked': ( 'The scraper was blocked by this site. ' 'Try again in a few hours or enter the URL manually.' ), 'scrape_timeout': 'The page took too long to load. This may be a temporary issue.', 'extract_failed': ( 'The AI could not extract structured data from this page. ' 'The page structure may have changed.' ), 'url_not_found': ( 'No matching trip page was found for this competitor. ' 'Try entering the URL manually.' ), 'proxy_error': 'Proxy connection failed. Retrying with fallback provider.', }