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`.
|
- 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.
|
- 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) .`.
|
- 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_out = CreatePipe
|
||||||
, std_err = CreatePipe
|
, std_err = CreatePipe
|
||||||
}
|
}
|
||||||
(Just outH, Just errH, _, ph) <- createProcess process
|
result <- createProcess process
|
||||||
hSetBinaryMode outH True
|
case result of
|
||||||
hSetBinaryMode errH True
|
(Just outH, Just errH, _, ph) -> do
|
||||||
out <- LB.hGetContents outH
|
hSetBinaryMode outH True
|
||||||
err <- LB.hGetContents errH
|
hSetBinaryMode errH True
|
||||||
ec <- waitForProcess ph
|
out <- LB.hGetContents outH
|
||||||
return (ec, out, err)
|
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.
|
-- | Locate the scrape-recipe script: check PATH first, then relative to project.
|
||||||
findScrapeScript :: IO FilePath
|
findScrapeScript :: IO FilePath
|
||||||
|
|||||||
Reference in New Issue
Block a user