From 5753b91f5b20cb41c32bf510b3b9a31486dd3503 Mon Sep 17 00:00:00 2001 From: Krish Talati Date: Tue, 17 Feb 2026 19:41:44 -0500 Subject: [PATCH] Improve error message for malformed JSON in request body --- QUICK_TEST.md | 39 +++++++++ TESTING_GUIDE.md | 169 +++++++++++++++++++++++++++++++++++++ TEST_COMMANDS.md | 76 +++++++++++++++++ httpie/cli/requestitems.py | 8 ++ tests/test_json.py | 23 +++++ 5 files changed, 315 insertions(+) create mode 100644 QUICK_TEST.md create mode 100644 TESTING_GUIDE.md create mode 100644 TEST_COMMANDS.md diff --git a/QUICK_TEST.md b/QUICK_TEST.md new file mode 100644 index 0000000000..0f0c7019df --- /dev/null +++ b/QUICK_TEST.md @@ -0,0 +1,39 @@ +# Quick Test Commands + +## Test the Improved Error Message + +### Windows CMD: +```cmd +python -m httpie POST https://httpbin.org/post "data:={\"bad json\"}" +``` + +### Windows PowerShell: +```powershell +python -m httpie POST https://httpbin.org/post "data:={\"bad json\"}" +``` + +### What you should see: +``` +http: error: 'data:={"bad json"}': Invalid JSON provided in request body. +Check your quotes, commas, and brackets. +Example: + data:='{"name": "John"}' +``` + +### Verify Exit Code (PowerShell): +```powershell +python -m httpie POST https://httpbin.org/post "data:={\"bad json\"}" +$LASTEXITCODE # Should show 1 +``` + +### Verify Exit Code (CMD): +```cmd +python -m httpie POST https://httpbin.org/post "data:={\"bad json\"}" +echo %ERRORLEVEL% # Should show 1 +``` + +### Test Valid JSON (should work normally): +```cmd +python -m httpie POST https://httpbin.org/post "data:={\"name\": \"John\", \"age\": 30}" +``` + diff --git a/TESTING_GUIDE.md b/TESTING_GUIDE.md new file mode 100644 index 0000000000..a76524d6d8 --- /dev/null +++ b/TESTING_GUIDE.md @@ -0,0 +1,169 @@ +# Testing Guide for Malformed JSON Error Improvement + +This guide shows you how to test the improved error message for malformed JSON in HTTPie. + +## Prerequisites + +1. **Install dependencies** (if not already installed): + ```bash + pip install -e ".[test]" + ``` + Or if you prefer to install manually: + ```bash + pip install pytest pytest-httpbin responses pytest-mock werkzeug + ``` + +## Method 1: Run the Unit Test + +Run the specific test we added: + +```bash +# Run just the malformed JSON test +pytest tests/test_json.py::test_malformed_json_error -v + +# Or run all JSON tests +pytest tests/test_json.py -v +``` + +Expected output should show the test passing: +``` +tests/test_json.py::test_malformed_json_error PASSED +``` + +## Method 2: Test Manually with HTTPie CLI + +### Test 1: Malformed JSON (should show friendly error) + +```bash +# This should show the new friendly error message +python -m httpie POST https://httpbin.org/post data:='{"bad json"}' +``` + +**Expected output:** +``` +usage: http [--json] [--form] [--multipart] [--boundary BOUNDARY] ... +http: error: 'data:={"bad json"}': Invalid JSON provided in request body. +Check your quotes, commas, and brackets. +Example: + data:='{"name": "John"}' +``` + +**Verify exit code is non-zero:** +```bash +python -m httpie POST https://httpbin.org/post data:='{"bad json"}' +echo $? # On Linux/Mac, should print 1 +# On Windows PowerShell: +$LASTEXITCODE # Should be 1 +``` + +### Test 2: Valid JSON (should work normally) + +```bash +# This should work without errors +python -m httpie POST https://httpbin.org/post data:='{"name": "John", "age": 30}' +``` + +**Expected:** Request should be sent successfully (or show normal HTTP response). + +### Test 3: Other malformed JSON examples + +Try these to see the error message: + +```bash +# Missing closing brace +python -m httpie POST https://httpbin.org/post data:='{"name": "John"' + +# Missing quotes +python -m httpie POST https://httpbin.org/post data:='{name: "John"}' + +# Trailing comma +python -m httpie POST https://httpbin.org/post data:='{"name": "John",}' +``` + +## Method 3: Test with Python Script + +Create a test script to verify the error handling: + +```python +#!/usr/bin/env python +"""Test malformed JSON error handling.""" + +import sys +sys.path.insert(0, '.') + +from httpie.cli.exceptions import ParseError +from httpie.cli.requestitems import load_json +from httpie.cli.argtypes import KeyValueArg + +# Test malformed JSON +arg = KeyValueArg( + key='data', + value='{"bad json"}', + sep=':=', + orig='data:={"bad json"}' +) + +try: + load_json(arg, '{"bad json"}') + print("ERROR: Should have raised ParseError") + sys.exit(1) +except ParseError as e: + print("✓ Error caught correctly!") + print(f"\nError message:\n{str(e)}\n") + + # Verify message contains expected parts + msg = str(e) + checks = [ + 'Invalid JSON provided in request body', + 'Check your quotes, commas, and brackets', + 'Example:' + ] + + for check in checks: + if check in msg: + print(f"✓ Contains: {check}") + else: + print(f"✗ Missing: {check}") + sys.exit(1) + + print("\n✓ All checks passed!") +``` + +Run it: +```bash +python test_script.py +``` + +## Method 4: Run All Tests + +To make sure nothing broke: + +```bash +# Run all tests +pytest + +# Run just the JSON-related tests +pytest tests/test_json.py -v + +# Run with coverage (if pytest-cov is installed) +pytest --cov=httpie tests/test_json.py +``` + +## Expected Behavior Summary + +✅ **Malformed JSON**: Shows friendly error message, exits with code 1 +✅ **Valid JSON**: Works normally, no errors +✅ **Exit Code**: Non-zero (1) on JSON parse errors +✅ **Error Message**: Contains all required elements: + - "Invalid JSON provided in request body" + - "Check your quotes, commas, and brackets" + - Example showing correct syntax + +## Troubleshooting + +If tests fail: +1. Make sure dependencies are installed: `pip install -e ".[test]"` +2. Make sure you're in the project root directory +3. Check Python version: `python --version` (should be 3.7+) +4. Try running with verbose output: `pytest -vv tests/test_json.py::test_malformed_json_error` + diff --git a/TEST_COMMANDS.md b/TEST_COMMANDS.md new file mode 100644 index 0000000000..ecb93b6059 --- /dev/null +++ b/TEST_COMMANDS.md @@ -0,0 +1,76 @@ +# Exact Commands to Test + +## Important: Use the Local Modified Code + +You need to make sure you're using the modified code, not an installed version. + +### Option 1: Install in Development Mode (Recommended) +```cmd +cd C:\Users\Krish\Downloads\new_http\httpie +pip install -e . +``` + +Then test with: +```cmd +python -m httpie POST https://httpbin.org/post "data:={\"bad json\"}" +``` + +### Option 2: Run from Project Directory with PYTHONPATH +```cmd +cd C:\Users\Krish\Downloads\new_http\httpie +set PYTHONPATH=%CD% +python -m httpie POST https://httpbin.org/post "data:={\"bad json\"}" +``` + +### Option 3: Use Python Script Directly +```cmd +cd C:\Users\Krish\Downloads\new_http\httpie +python -m httpie POST https://httpbin.org/post "data:={\"bad json\"}" +``` + +## Exact Command to Run + +### Windows CMD: +```cmd +python -m httpie POST https://httpbin.org/post "data:={\"bad json\"}" +``` + +### Windows PowerShell: +```powershell +python -m httpie POST https://httpbin.org/post "data:={\"bad json\"}" +``` + +### Alternative (if quotes are tricky): +```cmd +python -m httpie POST https://httpbin.org/post data:='{"bad json"}' +``` + +## What You Should See + +### ❌ OLD Error (before our changes): +``` +http: error: 'data:={"bad json"}': Expecting property name enclosed in double quotes: line 1 column 2 (char 1) +``` + +### ✅ NEW Error (after our changes): +``` +http: error: 'data:={"bad json"}': Invalid JSON provided in request body. +Check your quotes, commas, and brackets. +Example: + data:='{"name": "John"}' +``` + +## Verify You're Using Local Code + +Check which version is being used: +```cmd +python -c "import httpie.cli.requestitems; print(httpie.cli.requestitems.__file__)" +``` + +Should show: `C:\Users\Krish\Downloads\new_http\httpie\httpie\cli\requestitems.py` + +If it shows a different path (like in site-packages), you need to install in dev mode: +```cmd +pip install -e . +``` + diff --git a/httpie/cli/requestitems.py b/httpie/cli/requestitems.py index 8931b88ac7..fd405f49ae 100644 --- a/httpie/cli/requestitems.py +++ b/httpie/cli/requestitems.py @@ -1,4 +1,5 @@ import os +import json import functools from typing import Callable, Dict, IO, List, Optional, Tuple, Union @@ -226,5 +227,12 @@ def load_text_file(item: KeyValueArg) -> str: def load_json(arg: KeyValueArg, contents: str) -> JSONType: try: return load_json_preserve_order_and_dupe_keys(contents) + except json.JSONDecodeError: + raise ParseError( + f'{arg.orig!r}: Invalid JSON provided in request body.\n' + 'Check your quotes, commas, and brackets.\n' + 'Example:\n' + " data:='{\"name\": \"John\"}'" + ) except ValueError as e: raise ParseError(f'{arg.orig!r}: {e}') diff --git a/tests/test_json.py b/tests/test_json.py index e758ebe7f4..aae91b71ff 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -160,6 +160,29 @@ def test_complex_json_arguments_with_non_json(httpbin, request_type, value): cm.match('Cannot use complex JSON value types') +def test_malformed_json_error(): + """Test that malformed JSON in request body shows a user-friendly error.""" + from httpie.cli.exceptions import ParseError + from httpie.cli.requestitems import load_json + from httpie.cli.argtypes import KeyValueArg + + # Create a KeyValueArg for malformed JSON + arg = KeyValueArg( + key='data', + value='{"bad json"}', + sep=':=', + orig='data:={"bad json"}' + ) + + with pytest.raises(ParseError) as cm: + load_json(arg, '{"bad json"}') + + error_message = str(cm.value) + assert 'Invalid JSON provided in request body' in error_message + assert 'Check your quotes, commas, and brackets' in error_message + assert 'Example:' in error_message + + @pytest.mark.parametrize( 'input_json, expected_json', [