fix: replace partial pattern in readProcessBytes with explicit case
Build and Deploy / build-and-deploy (push) Successful in 1m28s
Build and Deploy / build-and-deploy (push) Successful in 1m28s
Also adds type-safety conventions to AGENTS.md: no partial patterns on IO results, no partial functions (head/tail/fromJust), always use case with explicit branches.
This commit is contained in:
@@ -86,3 +86,28 @@ mkdir -p .stack-root
|
||||
- When adding a new subproject (e.g. `roux-server`), initialize it with `./hs stack new`.
|
||||
- Use `hpack` (via `./hs hpack`) for package metadata in `package.yaml` format.
|
||||
- When agent-created files are owned by root, fix ownership with `sudo chown -R $(id -u):$(id -g) .`.
|
||||
|
||||
### Type safety and pattern matching
|
||||
|
||||
This project compiles with `-Wall -Werror`, including `-Wincomplete-uni-patterns`
|
||||
and `-Wincomplete-record-updates`. Partial functions and irrefutable pattern
|
||||
matches (`let (Just x) = ...`, `(Just x, _) <- ...`) will fail at runtime or
|
||||
be rejected by the compiler.
|
||||
|
||||
**Rules:**
|
||||
|
||||
- **Never** use irrefutable/partial pattern matches on `Maybe`, `Either`, or
|
||||
tuple results from `IO` actions. Always use `case` with an explicit branch
|
||||
for each constructor, or use pattern-matching helpers (`maybe`, `either`).
|
||||
- **Never** call partial functions: `head`, `tail`, `init`, `last`, `fromJust`,
|
||||
`read` (use `readMaybe`), `succ`, `pred`, `(!!)`. Use total alternatives:
|
||||
`foldl'` for `head`/`tail` on lists, `Data.Map.lookup` for map access,
|
||||
`take 1` or pattern matching on `NonEmpty`.
|
||||
- **Never** use `error`, `undefined`, or `panic` for recoverable failures.
|
||||
Use `Either`, `Maybe`, or explicit `IO` error handling (`ioError`,
|
||||
`Control.Exception.throwIO`).
|
||||
- **Always** fully handle all constructors in case expressions. Use a wildcard
|
||||
(`_ ->`) only when you genuinely don't care about the value, and add a
|
||||
comment explaining why.
|
||||
- **Prefer** `case` over `<-` pattern binds in `do` notation when the pattern
|
||||
could conceivably fail at runtime.
|
||||
|
||||
+13
-7
@@ -243,13 +243,19 @@ readProcessBytes cmd args = do
|
||||
{ std_out = CreatePipe
|
||||
, std_err = CreatePipe
|
||||
}
|
||||
(Just outH, Just errH, _, ph) <- createProcess process
|
||||
hSetBinaryMode outH True
|
||||
hSetBinaryMode errH True
|
||||
out <- LB.hGetContents outH
|
||||
err <- LB.hGetContents errH
|
||||
ec <- waitForProcess ph
|
||||
return (ec, out, err)
|
||||
result <- createProcess process
|
||||
case result of
|
||||
(Just outH, Just errH, _, ph) -> do
|
||||
hSetBinaryMode outH True
|
||||
hSetBinaryMode errH True
|
||||
out <- LB.hGetContents outH
|
||||
err <- LB.hGetContents errH
|
||||
ec <- waitForProcess ph
|
||||
pure (ec, out, err)
|
||||
_ ->
|
||||
ioError $
|
||||
userError $
|
||||
"[roux] createProcess did not return std_out/std_err pipes for " <> cmd
|
||||
|
||||
-- | Locate the scrape-recipe script: check PATH first, then relative to project.
|
||||
findScrapeScript :: IO FilePath
|
||||
|
||||
Reference in New Issue
Block a user