-
Notifications
You must be signed in to change notification settings - Fork 38
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
Add error handling for file loading #353
Conversation
tntc/cli-tests.md
Outdated
<!-- !test program | ||
bash - | ||
--> | ||
|
||
<!-- !test in non-existent file --> | ||
tntc parse ../examples/non-existent.file | ||
|
||
<!-- !test exit 1 --> | ||
<!-- !test err non-existent file --> | ||
error: file ../examples/non-existent.file does not exist |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is closer to the intended usage of the txm library than what I see in this file. In particular, it saves us having to duplicate each example by writing the program input in a code block under the program
. Removing this copy-pasta serves the aims of correctness, since it reduces the chance that the visible documentation of our tests will diverge from what is actually being tested.
This approach lets us specify program input and the expected output (along with any error codes) rather than having us define a new program for each test case. Because we are testing a CLI app, our "program" is just the shell, and and our input is the invocation of our command :)
If y'all agree, I can do a pass to fix the rest of the integration tests here. WDYT, @bugarela ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks much better! Please do and I'd say you could close #42 on the way 😄
const res = loadFile(argv.input) | ||
if (res.isRight()) { | ||
return parseText(argv, res.value) | ||
} else { | ||
console.error(res.value) | ||
process.exit(1) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a nice way to handle the errors here: instead, we should chance the error-prone computations, and have error reporting at the outermost layer. But I'm introducing the change in this way just to open the conversation.
If anyone feels strongly about avoiding use of Either
to faciliate composition of our error-apt computations here, I can revert this easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should totally use Either
here. There are some other parse and name resolution functions that return kind: 'ok'
or kind: 'error'
objects instead of Either
because we wrote them before introducing the Either library
. We should update all of them at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent. I'll swap this over while I'm refactoring to get the type map out. Thanks for the guidance and confirmation :)
} | ||
|
||
// a callback to parse the text that we get from readFile | ||
function parseText(argv: any, text: string): [Phase1Result, LookupTableByModule, string] { | ||
const path = resolve(cwd(), argv.input) | ||
const phase1Result = parsePhase1(text, path) | ||
if (phase1Result.kind === 'error') { | ||
reportError(argv, text, phase1Result) | ||
reportParseError(argv, text, phase1Result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just an incidental change to document the nature of this function, which is not suitable for general purpose error reporting.
Hmm, not sure why the windows test is failing... will have to try to debug a git. Unless anyone has alternative ideas on how to test the error output here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking into the integration tests!
const res = loadFile(argv.input) | ||
if (res.isRight()) { | ||
return parseText(argv, res.value) | ||
} else { | ||
console.error(res.value) | ||
process.exit(1) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should totally use Either
here. There are some other parse and name resolution functions that return kind: 'ok'
or kind: 'error'
objects instead of Either
because we wrote them before introducing the Either library
. We should update all of them at some point.
My shell knowledge is very limited, specially on windows. Sorry, I have no idea. The only thing I thought was that you removed the |
Funny enough, I removed this flag because it was failing on my system, with txm saying the flag is unsupported. But our CI isn't actually running that command, rather it runs https://github.com/informalsystems/tnt/blob/b31ff1f1e4b1aa6071564f1c29125a9e8d8e6bb8/.github/workflows/main.yml#L46 :) I think the failure on windows was initially due to windows line endings not matching the line endings in the output to compare against... but not sure! |
Looks to me like it may be a bug in tmx, and I've filed an issue anko/txm#10 |
Relative link will work on github but also for navigating around locally.
Closes #215 This is introduced in a way to suggest turning to sweet-monads/either for sequencing our error-prone computations. The sequencing and composition of our top-level routines exposed by CLI is currently done via imperative early exits. This makes it hard to reason about the code in general, but also breaks our ability to compose these routines. Looking towards #345, we'll need typecheck to receive the output of parse, then add it's typing information, before finally printing to the `--out` location. This requires composing the routines while handling possible error states, and just bailing with exit codes won't work for that. Since we are already using `Either`, and since it is designed for facilitating the composition of error-prone code, I think we can massage these routines into shape with a few well-placed Either's. ;)
`txm` does not support a `--no-color` flag as far as I can tell: indeed, we don't call it with this flag in our CI.
41ca7b2
to
0dcffd8
Compare
8340b36
to
5d3700e
Compare
5d3700e
to
a0cb9cb
Compare
As per our discussion in the standup, I've broken out the IO integrations tests, i.e., those that actually inspect output, into their own file, and I've configured the workflow to only run that file if we are not on windows. |
Thanks for the review! |
Closes #215
This is introduced in a way to suggest turning to sweet-monads/either
for sequencing our error-prone computations.
The sequencing and composition of our top-level routines exposed by CLI
is currently done via imperative early exits. This makes it hard to
reason about the code in general, but also breaks our ability to compose
these routines. Looking towards #345, we'll need typecheck to receive
the output of parse, then add it's typing information, before finally
printing to the
--out
location. This requires composing the routineswhile handling possible error states, and just bailing with exit codes
won't work for that. Since we are already using
Either
, and since itis designed for facilitating the composition of error-prone code, I
think we can massage these routines into shape with a few well-placed
Either's. ;)
I've added a few notes in commits and review comments to explain some of the
choices.