Skip to content

Conversation

@fkj
Copy link
Collaborator

@fkj fkj commented Oct 7, 2025

This pattern is dangerous because it makes it easy to write very subtle bugs that ignore error handling.

@fkj fkj force-pushed the add-do-result-ignore-analyzer branch 3 times, most recently from c991849 to b31f613 Compare October 15, 2025 13:08
@mickhansen
Copy link

I have a reasonable use case for Result.ignore, it's nice to use with traverseResultA which can yield a unit list

@fkj
Copy link
Collaborator Author

fkj commented Oct 15, 2025

I have a reasonable use case for Result.ignore, it's nice to use with traverseResultA which can yield a unit list

Sure, it can be useful in general. This is just to disallow the pattern do! ... |> Result.ignore and variants.

@mickhansen
Copy link

Sure, it can be useful in general. This is just to disallow the pattern do! ... |> Result.ignore and variants.

do! List.traverseResultA (fun -> ...) |>Result.ignore is a pattern I used recently.

@fkj
Copy link
Collaborator Author

fkj commented Oct 15, 2025

Sure, it can be useful in general. This is just to disallow the pattern do! ... |> Result.ignore and variants.

do! List.traverseResultA (fun -> ...) |>Result.ignore is a pattern I used recently.

Can you send me a link to the code where this was necessary?

@mickhansen
Copy link

mickhansen commented Oct 15, 2025

@fkj
Copy link
Collaborator Author

fkj commented Oct 15, 2025

Can you send me a link to the code where this was necessary?

Guess I used Result.map ignore

https://github.com/criipto/signatures-api/blob/068e61dead95871bd1a2dec7bde17f1dea477ab7/GraphQL/Schema/SignMutation.fs#L154

https://github.com/criipto/signatures-api/blob/068e61dead95871bd1a2dec7bde17f1dea477ab7/GraphQL/Schema/SignMutation.fs#L713

Same, same - the analyzer will find both patterns.

In the first case, the analyzer will not be triggered because the Result.map ignore call is not the final thing in the pipeline. So if the Result is accidentally double-wrapped, the types are unlikely to work out, which would cause a type error.

The second case could be written with Result.map (List.reduce (fun () () -> ())) instead of Result.ignore to make it safer. Maybe it would be useful to define our own function for the overall "traverse a list and stop on the first error, but don't give me the result" use case?

This pattern is dangerous because it makes it easy to write very subtle
bugs that ignore error handling.
@fkj fkj force-pushed the add-do-result-ignore-analyzer branch from b31f613 to 7be1d96 Compare November 21, 2025 15:37
@fkj
Copy link
Collaborator Author

fkj commented Nov 21, 2025

Results of running on the Verify solution

7 occurrences detected, none of which were false positives.
All occurrences were validation code which is the target of the analyzer.
Almost of the occurrences look like they could be fixed with minor rewrites.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants