-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce an HpackException
type, for Hpack exceptions
#530
Comments
The `Show` instance for `HpackException` preserves the existing error messages of all existing Hpack exceptions. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.ProgramName` because `Hpack.Exception` needs to import the type and `Hpack.Config` now imports `Hpack.Exception`. Also bumps Hpack's `stack.yaml` to use lts-20.0 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
The `Show` instance for `HpackException` preserves the existing error messages of all existing Hpack exceptions. Updates tests accordingly. Some tests use `shouldSatisfy` rather than `shouldReturn` as `HpackException` cannot be an instance of `Eq`. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.ProgramName` because `Hpack.Exception` needs to import the type and `Hpack.Config` now imports `Hpack.Exception`. Also bumps Hpack's `stack.yaml` to use lts-20.0 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
For GHC I see value in having identifiable and stable error messages. In the past I've been parsing GHC error messages myself and both the fact that GHC pretty prints them (leading to variations in line breaks and indentation) and that the format is not stable across GHC versions is a pain. For Hpack I don't have the insight to judge if effort spent here will provide benefits that amortize that effort. However, from the perspective of a user of the Hpack API I still think it's reasonable to want access to parse errors etc.
Exceptions are for unexpected situations. That a user has a syntax error in |
@sol, thanks. Currently, Hpack has (extracts): type Errors = ExceptT String
readPackageConfig :: DecodeOptions -> IO (Either String DecodeResult) and, where the action is yielded: hpackResultWithVersion :: Version -> Options -> IO Result
hpackResultWithVersion v (Options options force generateHashStrategy toStdout) = do
DecodeResult pkg (lines -> cabalVersion) cabalFileName warnings <- readPackageConfig options >>= either die return That is, Hpack uses My pull request (#531) replaces that with: type Errors = ExceptT HpackException
readPackageConfig :: DecodeOptions -> IO (Either HpackException DecodeResult) and hpackResultWithVersion :: Version -> Options -> IO Result
hpackResultWithVersion v (Options options force generateHashStrategy toStdout) = do
DecodeResult pkg (lines -> cabalVersion) cabalFileName warnings <- readPackageConfig options >>= either throwIO return that is, rather than |
As an example of what end users experience,
The first line is what Hpack outputs into After pull request #531, the user of Stack would receive this output:
Hpack's message is conveyed in the informative exception. |
@mpilgrem I would love to discuss this at length, but the amount of time I'm able to spend on this is limited. For that reason we have to handle this efficiently. I looked at your PR and I estimate that we will need five rounds of review to get this in shape. To avoid any further confusion I will leave a comment on your PR. |
That's what I'm suggesting instead:
|
The `Exception` instance for `HpackException` preserves the existing error messages of all existing Hpack exceptions in the `displayException` functions. Updates tests accordingly. Some tests use `shouldSatisfy` rather than `shouldReturn` as `HpackException` cannot be an instance of `Eq`. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.ProgramName` because `Hpack.Exception` needs to import the type and `Hpack.Config` now imports `Hpack.Exception`. Also bumps Hpack's `stack.yaml` to use lts-20.0 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
The `Exception` instance for `HpackException` preserves the existing error messages of all existing Hpack exceptions in the `displayException` functions. Updates tests accordingly. Some tests use `shouldSatisfy` rather than `shouldReturn` as `HpackException` cannot be an instance of `Eq`. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.ProgramName` because `Hpack.Exception` needs to import the type and `Hpack.Config` now imports `Hpack.Exception`. Also bumps Hpack's `stack.yaml` to use lts-20.0 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
The `Exception` instance for `HpackException` preserves the existing error messages of all existing Hpack exceptions in the `displayException` functions. Updates tests accordingly. Some tests use `shouldSatisfy` rather than `shouldReturn` as `HpackException` cannot be an instance of `Eq`. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.ProgramName` because `Hpack.Exception` needs to import the type and `Hpack.Config` now imports `Hpack.Exception`. Also bumps Hpack's `stack.yaml` to use lts-20.0 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
The `HpackError` type is an instance of `Eq`. Consequently, its data constructors involve only values of types that are instances of `Eq`. The `renderHpackError :: ProgramName -> HpackError -> String` function preserves the existing error messages of all existing Hpack errors. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.Error` because `renderHpackError` makes use of the type. Defines, and applies, `hpackProgName :: ProgramName`, for convenience. The `DecodeOptions` constructor no longer needs its `decodeOptionsProgramName :: ProgramName` field (and `setProgramName` falls away). Its `decodeOptionsDecode` field is of type `FilePath -> IO (Either HpackError ([String], [Value]))`. The module "Hpack" exports new function `hpackResultWithError :: Options -> IO (Either HpackError Result)`. Updates tests accordingly. Some tests use `shouldSatisfy` rather than `shouldReturn`. Also bumps Hpack's `stack.yaml` to use lts-20.1 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
The `HpackError` type is an instance of `Eq`. Consequently, its data constructors involve only values of types that are instances of `Eq`. The `renderHpackError :: ProgramName -> HpackError -> String` function preserves the existing error messages of all existing Hpack errors. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.Error` because `renderHpackError` makes use of the type. Defines, and applies, `hpackProgName :: ProgramName`, for convenience. The `DecodeOptions` constructor no longer needs its `decodeOptionsProgramName :: ProgramName` field (and `setProgramName` falls away). Its `decodeOptionsDecode` field is of type `FilePath -> IO (Either HpackError ([String], [Value]))`. The module "Hpack" exports new function `hpackResultWithError :: Options -> IO (Either HpackError Result)`. Updates tests accordingly. Some tests use `shouldSatisfy` rather than `shouldReturn`. Also bumps Hpack's `stack.yaml` to use lts-20.1 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
The `HpackError` type is an instance of `Eq`. Consequently, its data constructors involve only values of types that are instances of `Eq`. The `renderHpackError :: ProgramName -> HpackError -> String` function preserves the existing error messages of all existing Hpack errors. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.Error` because `renderHpackError` makes use of the type. Defines, and applies, `hpackProgName :: ProgramName`, for convenience. The `DecodeOptions` constructor no longer needs its `decodeOptionsProgramName :: ProgramName` field (and `setProgramName` falls away). Its `decodeOptionsDecode` field is of type `FilePath -> IO (Either HpackError ([String], [Value]))`. The module "Hpack" exports new function `hpackResultWithError :: Options -> IO (Either HpackError Result)`. Updates tests accordingly. Some tests use `shouldSatisfy` rather than `shouldReturn`. Also bumps Hpack's `stack.yaml` to use lts-20.1 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
The `HpackError` type is an instance of `Eq`. Consequently, its data constructors involve only values of types that are instances of `Eq`. The `renderHpackError :: ProgramName -> HpackError -> String` function preserves the existing error messages of all existing Hpack errors. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.Error` because `renderHpackError` makes use of the type. Defines, and applies, `hpackProgName :: ProgramName`, for convenience. The `DecodeOptions` constructor no longer needs its `decodeOptionsProgramName :: ProgramName` field (and `setProgramName` falls away). Its `decodeOptionsDecode` field is of type `FilePath -> IO (Either HpackError ([String], [Value]))`. The module "Hpack" exports new function `hpackResultWithError :: Options -> IO (Either HpackError Result)`. Updates tests accordingly. Some tests use `shouldSatisfy` rather than `shouldReturn`. Also bumps Hpack's `stack.yaml` to use lts-20.1 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
The `HpackError` type is an instance of `Eq`. Consequently, its data constructors involve only values of types that are instances of `Eq`. The `renderHpackError :: ProgramName -> HpackError -> String` function preserves the existing error messages of all existing Hpack errors. Moves `ProgramName` from `Hpack.Config` to new module `Hpack.Error` because `renderHpackError` makes use of the type. Defines, and applies, `hpackProgName :: ProgramName`, for convenience. The `DecodeOptions` constructor no longer needs its `decodeOptionsProgramName :: ProgramName` field (and `setProgramName` falls away). Its `decodeOptionsDecode` field is of type `FilePath -> IO (Either HpackError ([String], [Value]))`. The module "Hpack" exports new function `hpackResultWithError :: Options -> IO (Either HpackError Result)`. Updates tests accordingly. Some tests use `shouldSatisfy` rather than `shouldReturn`. Also bumps Hpack's `stack.yaml` to use lts-20.1 (GHC 9.2.5) rather than lts-15.11 (GHC 8.8.3).
For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds).
For the context to this pull request, see see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds). See also [Pantry PR #74](commercialhaskell/pantry#74) (on which this PR builds).
For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds).
For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds).
For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds).
For the context to this pull request, see see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds). See also [Pantry PR #74](commercialhaskell/pantry#74) (on which this PR builds).
For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds).
For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds).
For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds).
For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds).
For the context to this pull request, see see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds). See also [Pantry PR #74](commercialhaskell/pantry#74) (on which this PR builds).
Addressed by #535. |
Prettier Hpack error messages are enabled by hpack-0.35.1. For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds). Also bumps from lts-20.0 to lts-20.4 (most recent GHC 9.2.5).
Prettier Hpack error messages are enabled by hpack-0.35.1. For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds). Also conforms form of messages of Errors [S-305] and [S-720]. Also bumps from lts-20.0 to lts-20.4 (most recent GHC 9.2.5).
Prettier Hpack error messages are enabled by hpack-0.35.1. For the context to this pull request see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds). Also conforms form of messages of Errors [S-305] and [S-720] and the naming of arguments (`err`) in the `PantryException` instance of `Display`. Also bumps from lts-20.0 to lts-20.4 (most recent GHC 9.2.5).
For the context to this pull request, see see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds). See also [Pantry PR #74](commercialhaskell/pantry#74) (on which this PR builds).
For the context to this pull request, see see [Hpack issue #530](sol/hpack#530), the [Hpack PR #531](sol/hpack#531) and the alternative [Hpack PR #535](sol/hpack#535) (on which this PR builds). See also [Pantry PR #74](commercialhaskell/pantry#74) (on which this PR builds).
I have been looking at Stack's exceptions, as part of the Haskell Foundation's Haskell Error Index initiative. That has taken me to the Pantry library, and then from Pantry to Hpack.
At the moment, Hpack uses
String
as its exception type and ends withSystem.Exit.die :: String -> IO a
. This prints an error message tostderr
and then throws an uninformative exception (ExitFailure 1
). I propose to introduce anHpackException
type for Hpack exceptions, which would produce the error message when the exception is thrown. That type would allow users of the Hpack library to catch the exceptions and give a different output to the one Hpack chooses to deliver, if they wished.I have a pull request that implements this proposal and preserves Hpack's current exception messages, which I will raise.
The text was updated successfully, but these errors were encountered: