JSON and CSV · practice
Report Malformed Input
The project now rejects bad data where it discovers it. Try the two seeded failures from a temporary line in the editor or the Python console:
read_catalog_csv("bad_catalog.csv")
read_catalog_json("bad_catalog.json")
The first reaches a row whose quantity is many. The second ends before its array and catalog.json.
Catch at the user-facing boundary
Low-level main is where a short, actionable message becomes more useful than a full
The converter can reasonably expect:
FileNotFoundErrorwhen the named input is absent;UnicodeDecodeErrorwhen a supposed UTF-8 input is not UTF-8;csv.Errorfor broken CSV quoting;ValueErrorfor the schema andrules. json.JSONDecodeErroris aValueErrorsubclass, so this also covers malformed JSON when the JSON reader is used by another caller.
Catch only that except Exception would also hide TypeError from a programming mistake inside the converter and mislabel it as bad data.
One deterministic command
Implement main() so it calls:
convert_catalog("catalog.csv", "catalog.json")
On expected failure, print Could not convert catalog: followed by the exception message and return 1. On success, print exactly:
Wrote 3 items to catalog.json.
Use the actual item count from the returned document and return 0.
Keep the existing guarded entry point. The guard makes importing catalog.py safe for tests and other programs, while pressing Run executes the command.
There is a quick way to check that your handler is narrow rather than all-catching. Temporarily add raise TypeError("boom") at the top of convert_catalog and run the program. You want a traceback, not Could not convert catalog: boom. A TypeError there means a defect in your own code, and dressing it up as bad input would send you looking in the wrong file. Remove the line afterwards.
If you are unsure which exceptions belong in the tuple, ask Monty: “Which of these failures mean bad input, and which mean a bug in my code?” That is the line the whole lesson is drawing.
Task
Implement main() around convert_catalog("catalog.csv", "catalog.json").
Catch only FileNotFoundError, UnicodeDecodeError, csv.Error, and 1. On success, print the actual item count in Wrote N items to catalog.json. and return 0. Leave unexpected programming errors visible.