diff --git a/CHANGELOG.md b/CHANGELOG.md index ed829fd..6f3d761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ New features: Bugfixes: +- Account for child creation to possibly fail with system error (#66 by @Hi-Angel) + Other improvements: ## [v11.1.0](https://github.com/purescript-node/purescript-node-child-process/releases/tag/v11.1.0) - 2023-11-14 @@ -76,7 +78,7 @@ Breaking changes: - Moved from `Node.ChildProces` to `Node.ChildProces.Types` - Changed the `BySignal`'s constructor's arg type from `Signal` to `String` - Breaking changes made to the `Handle` type (#46 by @JordanMartinez) - + - Moved from `Node.ChildProces` to `Node.ChildProces.Types` - Converted `defaultOptions { override = Just 1}` pattern to `(_ { override = Just 1})` (#46 by @JordanMartinez) diff --git a/bower.json b/bower.json index 1dab847..035a1a9 100644 --- a/bower.json +++ b/bower.json @@ -16,6 +16,7 @@ "package.json" ], "dependencies": { + "purescript-aff": "^7.0.0", "purescript-exceptions": "^6.0.0", "purescript-node-event-emitter": "https://github.com/purescript-node/purescript-node-event-emitter.git#^3.0.0", "purescript-foreign": "^7.0.0", diff --git a/src/Node/ChildProcess.purs b/src/Node/ChildProcess.purs index 8921441..b425d7a 100644 --- a/src/Node/ChildProcess.purs +++ b/src/Node/ChildProcess.purs @@ -21,7 +21,7 @@ -- | defined in this library that doesn't exist in the Node docs. -- | It exists to allow the end-user to append additional values to the `safeStdio` value -- | used here. For example, --- | +-- | -- | ``` -- | spawn' file args (_ { appendStdio = Just [ fileDescriptor8, pipe, pipe ]}) -- | ``` @@ -86,7 +86,7 @@ module Node.ChildProcess import Prelude -import Data.Maybe (Maybe(..), fromMaybe) +import Data.Maybe (Maybe(..), fromMaybe, isJust) import Data.Nullable (Nullable, toMaybe, toNullable) import Data.Posix (Pid, Gid, Uid) import Data.Posix.Signal (Signal) @@ -237,7 +237,11 @@ spawnSync command args = (UnsafeCP.spawnSync command args) <#> \r -> , exitStatus: case toMaybe r.status, toMaybe r.signal of Just c, _ -> Normally c _, Just s -> BySignal s - _, _ -> unsafeCrashWith $ "Impossible: `spawnSync` child process neither exited nor was killed." + _, _ -> + if isJust $ toMaybe r.error then + BySysError + else + unsafeCrashWith $ "Impossible: `spawnSync` child process neither exited nor was killed." , error: toMaybe r.error } @@ -282,7 +286,11 @@ spawnSync' command args buildOpts = (UnsafeCP.spawnSync' command args opts) <#> , exitStatus: case toMaybe r.status, toMaybe r.signal of Just c, _ -> Normally c _, Just s -> BySignal s - _, _ -> unsafeCrashWith $ "Impossible: `spawnSync` child process neither exited nor was killed." + _, _ -> + if isJust $ toMaybe r.error then + BySysError + else + unsafeCrashWith $ "Impossible: `spawnSync` child process neither exited nor was killed." , error: toMaybe r.error } where diff --git a/src/Node/ChildProcess/Types.purs b/src/Node/ChildProcess/Types.purs index 98f1370..ece2f8e 100644 --- a/src/Node/ChildProcess/Types.purs +++ b/src/Node/ChildProcess/Types.purs @@ -52,7 +52,7 @@ foreign import data StdIO :: Type -- | Note: when used with `stdin`, piping the parent stdin to this stream -- | will not cause the child process to terminate when that parent stdin stream -- | ends via `Ctrl+D` user input. Rather, the child process will hang --- | until the parent process calls `Stream.end` on the child process' +-- | until the parent process calls `Stream.end` on the child process' -- | `stdin` stream. Since it's impossible to know when the user -- | inputs `Ctrl+D`, `inherit` should be used instead. pipe :: StdIO @@ -140,12 +140,14 @@ customShell = unsafeCoerce -- | what options were used. foreign import data StringOrBuffer :: Type --- | Specifies how a child process exited; normally (with an exit code), or --- | due to a signal. +-- | Specifies how a child process exited; normally (with an exit code), due to +-- | a signal or if it failed to even launch (e.g. if a command doesn't exist). data Exit = Normally Int | BySignal KillSignal + | BySysError instance showExit :: Show Exit where show (Normally x) = "Normally " <> show x show (BySignal sig) = "BySignal " <> (either show show $ fromKillSignal sig) + show BySysError = "BySysError" diff --git a/test/Main.purs b/test/Main.purs index 2b973f3..3ad0b1e 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -72,6 +72,7 @@ spawnLs = do Normally 0 -> log $ "ls exited with 0" Normally i -> liftEffect $ throw $ "ls had non-zero exit: " <> show i BySignal sig -> liftEffect $ throw $ "ls exited with sig: " <> show sig + BySysError -> liftEffect $ throw "ls exited with system error" nonExistentExecutable :: Aff Unit nonExistentExecutable = do