Level 6.B ~25 min Target: PHPStan max
Boss: a supplier price import
The tea supplier uploaded a price list of 112 products and was told Imported 40 products. Six rows had been skipped, each with a line in a log nobody reads. Loose Earl Grey at £0.29 went into the catalogue at 28p. And on row 47 the database timed out, which the import caught, logged as one more bad row, and carried on from. Nobody can say which 40 got in.
ProductImport::run() is twenty lines long, and every one of World 6's mistakes is in it.
Your checklist
| Level | Ask of ProductImport |
|---|---|
| 6.1 Exceptions with names | Does it react to failures by their type, like InvalidSku, and never by reading a message? |
| 6.2 Never swallow | Does every catch name the one failure it handles, around only the call that throws it? |
| 6.3 Failure in the signature | Does @throws say what reaches the controller, and does PHPStan agree? |
| 6.4 Validation isn't exceptional | Does a bad file come back as ImportProblems with every bad line, not just the first? |
| 6.5 Leave it as you found it | If anything fails, is the catalogue exactly as it was before the upload? |
Floats are back for one last appearance, too. (float) '0.29' * 100 is 28.999999999999996, and (int) rounds it down. 5.2 said what to do about money, and it still applies when the money arrives as text.