-
Notifications
You must be signed in to change notification settings - Fork 20
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
Does OK.with handle raised errors? #40
Comments
rescue is for |
No, I get the problem, but don't you think "rescue" is confusing in this case? Not related, but are the values defined under the E.g if parsing a JSON string loaded from a file fails. static fileprivate func parseJSON(fromFileContent fileContent:FileSystemLoader.FileContent<String>) throws -> Parser.UnfilteredContent {
return try Either<Error, FileSystemLoader.FileContent<String>>
.right(fileContent)
.map { $0.content }
.map { $0.data(using: String.Encoding.utf8) }
.map { try $0.throwingIfNil(Parser.ParseError.failedEncodingFileContentToData(fileContent)) }
.map { try JSONSerialization.jsonObject(with: $0, options: []) }
.mapLeft { throw Parser.ParseError.failedParsingFromFileContent(fileContent, $0) }
.map { FileSystemLoader.FileContent(with: (raw:fileContent.content, processed:$0 as AnyObject), from: fileContent.file) }
.unwrapError()
}
``` |
Turns out it's not def ok do
OK.try do
file <- "priv/sample.json" |> File.read
content <- file |> Poison.Parser.parse
after
IO.inspect content
rescue
error -> IO.inspect file
end
end It would be nice to have access to have a list of the content before the failure without inserting them to a list outside the block |
That sounds like an interesting challenge. If the rescue block is called because yes I agree it's confusing. I think the only solution I have is a nice explanation on why exceptional cases (bad input) are not the same as programmer errors. I use OK to handle the former and raised errors just end up in by bug tracker. |
@CrowdHailer I think we're venturing outside the scope of this library, my bad. What I am looking for is not something where I match on a specific error, but a specific call. def ok do
OK.try do
content <- filename |> File.read as: {LoadingFile, filename}
parsed_content <- file |> Poison.Parser.parse as: {ParsingContent: [content, filename]}
after
IO.inspect parsed_content
rescue
{LoadingFile: filename} -> IO.inspect filename
{ParsingContent: [content, filename]} -> IO.inspect content
end
end Obviously it would be nice to also match on the error, but usually for me, I debug better when I can know where something failed and what it used to fail on. |
To be honest, I actually also prefer the piping way (like the Swift sample above) than using the "with" syntax. Some pseudo code operation = content
~~> happy_path
~~> until_something
~~> goes_wrong
~~> and_let_me_have_all
~~> the_info_to_match_on_the_wrong
case operation.result. do
{:ok, value} -> IO.inspect value
{:error, reason} -> IO.inspect reason
end
case operation.error. do
{:happy_path, [content | _]}
-> IO.inspect "Error occured on happy path with content "#{v}"
{: until_something, [result_from_happy_path | x]}
-> IO.inspect "Error occured on : until_something content "#{result_from_happy_path}"
{: goes_wrong, [result_from_until_something | x]}
-> IO.inspect "Error occured on : goes_wrong content "#{result_from_until_something}"
end |
That is much closer to the swift example you shared before. result = content
~>> happy_path
~>> until_something
~>> goes_wrong
~>> and_let_me_have_all
~>> the_info_to_match_on_the_wrong
case result do
{:ok, v} ->
{:error, v} ->
end
|
I am, in fact, I was looking at it as a base for something new. Maybe one could wrap |
https://github.com/CrowdHailer/OK/blob/master/lib/ok.ex#L141 I am guessing the first two lines here have something to do with the end clause value = quote do: value
args = [value | args]
#.......
unquote({call, line, args}) On inspecting value, and args, I find it to be empty but it should contain my argument ( |
What's your take on something like content = "filename.json"
operation =
content
|> Ok.pipable
~>> happy_path, as: :happy
~>> until_something
~>> goes_wrong, as: :wrongy
case operation.result. do
{:ok, value} -> IO.inspect value
{:error, reason} -> IO.inspect reason
end
case operation.error. do
{:happy, [filename | _]}
-> IO.inspect "Error occured on happy path with filename "#{v}"
{: until_something, [result_from_happy_path | x]}
-> IO.inspect "Error occured on : until_something content "#{result_from_happy_path}"
{: wrongy, [result_from_until_something | x]}
-> IO.inspect "Error occured on : goes_wrong content "#{result_from_until_something}"
end |
I'm not convinced I see that value for my code but I have got familiar with how |
That sounds good. You can feel free to close this if you're thinking of a different avenue to continue the discussion on.
I actually think Elixir would have been better if it treated everything as a "monad", even if it's just a tuple. |
@seivan thanks for your points here. Closing as I don't think this issue has any next action. apart from perhaps more docs/a blog post explaining the points but (speaking for my self) that's not happening soon and I already have a similar issue for that |
https://github.com/CrowdHailer/OK#oktry
Does that mean the cases under
rescue
are raised errors, or errors in{:error, reason}
?The text was updated successfully, but these errors were encountered: