Skip to content

Conversation

@cuihtlauac
Copy link
Collaborator

@cuihtlauac cuihtlauac commented Feb 23, 2023

  • General considerations on error handling
  • Predefined exceptions
  • Runtime crashes
  • Usage of the Option type

Discuss thread: https://discuss.ocaml.org/t/updating-the-error-handling-tutorial/12022

@cuihtlauac cuihtlauac marked this pull request as draft February 23, 2023 17:56
@cuihtlauac cuihtlauac mentioned this pull request Feb 28, 2023
18 tasks
@cuihtlauac cuihtlauac marked this pull request as ready for review March 1, 2023 16:22
exception Failure of string
```

* `Exit` terminates your program with a success status, which is 0 in Unices (they do error values)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"they do error values" is confusing here. Did you mean to mention that Unix-like systems have processes returning an exit value? Does this even matter in this tutorial?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the first section, I describe encoding errors as special values, as done in C. Mainly to state explicitly it shouldn't be done in OCAml. The text between the parenthesis is not a strict requirement for this tutorial, however, I'm tempted to believe it has some relevance. But I'm open to discussion. I agree the text needs to be clarified.


Properly handling errors is a complex matter. It is [cross-cutting
concern](https://en.wikipedia.org/wiki/Cross-cutting_concern), it touches all
parts of an application and can't be isolated in dedicated module. In contrast
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
parts of an application and can't be isolated in dedicated module. In contrast
parts of an application and can't be isolated in a dedicated module. In contrast

Properly handling errors is a complex matter. It is [cross-cutting
concern](https://en.wikipedia.org/wiki/Cross-cutting_concern), it touches all
parts of an application and can't be isolated in dedicated module. In contrast
to several other main stream languages, OCaml provides several mechanisms to
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
to several other main stream languages, OCaml provides several mechanisms to
to several other mainstream languages, OCaml provides several mechanisms to

concern](https://en.wikipedia.org/wiki/Cross-cutting_concern), it touches all
parts of an application and can't be isolated in dedicated module. In contrast
to several other main stream languages, OCaml provides several mechanisms to
handled exceptional circumstances, all with good runtime performances and code
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
handled exceptional circumstances, all with good runtime performances and code
handle exceptional circumstances, all with good runtime performance and code

to several other main stream languages, OCaml provides several mechanisms to
handled exceptional circumstances, all with good runtime performances and code
understandability. Using them properly requires some initial learning and
partice. Later, it always require some thinking, which is good since proper
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
partice. Later, it always require some thinking, which is good since proper
practice. Later, it always requires some thinking, which is good since proper

understandability. Using them properly requires some initial learning and
partice. Later, it always require some thinking, which is good since proper
management of errors shouldn't ever be overlooked. No error handling is better
than the others, and is should be matter of adequacy to the context rather some
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
than the others, and is should be matter of adequacy to the context rather some
than the others, and is should be matter of adequacy to the context rather than

Copy link
Contributor

@christinerose christinerose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly grammar/syntax suggestions. A few verb tense and typo corrections.
I didn't go over the code itself yet (to see if there are any gaps for a relative newbie), but I will shortly if you'd like.

```

And you will get a stacktrace. Alternatively, you can call, from within the program,
And you will get a stack trace. Alternatively, you can call, from within the program,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
And you will get a stack trace. Alternatively, you can call, from within the program,
This will produce a stack trace. Alternatively, you can call, from within the program,

(if my suggestion is correct!)

Comment on lines 734 to 771
Here, it would be wrong to use `failwith` since it requires the compiler to be
bugged or the system to be corrupted for second code path to be executed.
Breakage of the language semantics qualifies as extraordinary circumstances, it
is catastrophic.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Here, it would be wrong to use `failwith` since it requires the compiler to be
bugged or the system to be corrupted for second code path to be executed.
Breakage of the language semantics qualifies as extraordinary circumstances, it
is catastrophic.
Here, it wouldn't be beneficial to use `failwith` since it requires the compiler to be
bugged or the system to be corrupted for second code path to be executed.
Breakage of the language semantics qualifies as extraordinary circumstances; it
is catastrophic.

# Concluding Remarks

Properly handling errors is a complex matter. It is [cross-cutting
concern](https://en.wikipedia.org/wiki/Cross-cutting_concern), it touches all
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
concern](https://en.wikipedia.org/wiki/Cross-cutting_concern), it touches all
concern](https://en.wikipedia.org/wiki/Cross-cutting_concern); it touches all

to several other main stream languages, OCaml provides several mechanisms to
handled exceptional circumstances, all with good runtime performances and code
understandability. Using them properly requires some initial learning and
partice. Later, it always require some thinking, which is good since proper
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
partice. Later, it always require some thinking, which is good since proper
pratice. Later, it always require some thinking, which is good since proper

handled exceptional circumstances, all with good runtime performances and code
understandability. Using them properly requires some initial learning and
partice. Later, it always require some thinking, which is good since proper
management of errors shouldn't ever be overlooked. No error handling is better
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
management of errors shouldn't ever be overlooked. No error handling is better
error management shouldn't ever be overlooked. No error handling is better

understandability. Using them properly requires some initial learning and
partice. Later, it always require some thinking, which is good since proper
management of errors shouldn't ever be overlooked. No error handling is better
than the others, and is should be matter of adequacy to the context rather some
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
than the others, and is should be matter of adequacy to the context rather some
than the others, and it should be matter of adequacy to the context rather some

@cuihtlauac
Copy link
Collaborator Author

Thanks, @christinerose for your suggestions, that's great. I've committed them all. Yes if you want to test the code, that be nice too.

Exceptions belong to the type `exn` (an extensible sum type):
The biggest issue with exceptions is that they do not appear in types. One has
to read the documentation to see that, indeed, `List.find` or `String.sub` are
not total functions, and that they might fail by raising an exception.
Copy link
Contributor

@rikusilvola rikusilvola Mar 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Total functions? Could benefit from unwrapping.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain a little bit? I don't get what you mean

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing!

Since the document is intended for newcomers, those might include people unfamiliar with functional programming terminology. I would propose either a quick sidenote or a link to a definition, preferably on our site instead of on some other language's docs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The document on functional programming needs to be updated. I was planning to add that kind of text there. I'll link to it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like the right place.

@rikusilvola
Copy link
Contributor

rikusilvola commented Mar 2, 2023

Brilliant!
I especially appreciate the extensive coverage of bind in error handling.
Having the use of both the binding operators and the infix bind documented on ocaml.org will be beneficial for newcomers.
👍

@cuihtlauac
Copy link
Collaborator Author

Thanks, @rikusilvola. BTW, I considered adding some text on how to deal with permanent vs transient failures, à la SRE. Might make sense. I have vague memories of a Google documentation where code patterns where put in front of various kinds of failures, but I couldn't find it. Does not seem to be in the SRE book. Does it ring a bell to you?

Copy link
Contributor

@christinerose christinerose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving in the case all my questions/comments are irrelevant! 😄

Several expressions don't run, and it's not clear to me if they're supposed to run/output, be combined with something else to try it, or if it's just examples/information. I've left notes on several of those, but I stopped about 2/3 through to reduce the noise, as indicated in the last question about it.

A few expressions were missing the ;; to get the output, and I found one or two output errors/discrepancies.

I hope all this is helpful! Let me know about the code questions, and I can review it again. 🙂

- : int option = None
# String.sub "Hello world!" 3 (-2);;
Exception: Invalid_argument "String.sub / Bytes.sub".
# let rec loop x = x :: loop x
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# let rec loop x = x :: loop x
# let rec loop x = x :: loop x;;

And you will get a stack trace. Alternatively, you can call, from within the
program,

```ocaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the code li 160 - 191 examples of code the user will write themselves, or is it something the reader should be able to test when going through this doc?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, that's for reading only

| Some host_len -> Some (String.sub fqdn 0 host_len)
| None -> if fqdn <> "" then Some fqdn else None
end
| None -> None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I put the ;; at this end of this, I get this output val host_opt : string -> string option = <fun>

@cuihtlauac
Copy link
Collaborator Author

Several expressions don't run, and it's not clear to me if they're supposed to run/output, be combined with something else to try it, or if it's just examples/information. I've left notes on several of those, but I stopped about 2/3 through to reduce the noise, as indicated in the last question about it.

Since this keeps-on being a pain, I believe we have a more profound issue with code samples. I've filed this issue on the matter: #961

Let me know if it captures the difficulties you have. Starting from that we can consider, workarounds, to ease your work now and longer-termed solutions.

@christinerose
Copy link
Contributor

Several expressions don't run, and it's not clear to me if they're supposed to run/output, be combined with something else to try it, or if it's just examples/information. I've left notes on several of those, but I stopped about 2/3 through to reduce the noise, as indicated in the last question about it.

Since this keeps-on being a pain, I believe we have a more profound issue with code samples. I've filed this issue on the matter: #961

Let me know if it captures the difficulties you have. Starting from that we can consider, workarounds, to ease your work now and longer-termed solutions.

OMG! Thank you so much for making this PR. The comments that I already see are very validating that this could be done more clearly. I look forward to exploring the options with the team.

@rikusilvola
Copy link
Contributor

Thanks, @rikusilvola. BTW, I considered adding some text on how to deal with permanent vs transient failures, à la SRE. Might make sense. I have vague memories of a Google documentation where code patterns where put in front of various kinds of failures, but I couldn't find it. Does not seem to be in the SRE book. Does it ring a bell to you?

Hi @cuihtlauac ! No, I don't remember that from Google, but Microsoft has some good guidelines for transient fault handling as well as patterns for error handling for resilient applications. Maybe that's what you remember?

@cuihtlauac
Copy link
Collaborator Author

Hi @cuihtlauac ! No, I don't remember that from Google, but Microsoft has some good guidelines for transient fault handling as well as patterns for error handling for resilient applications. Maybe that's what you remember?

It must be it. Do you have the link or do you have tips on how I could find it myself?

@rikusilvola
Copy link
Contributor

Hi @cuihtlauac ! No, I don't remember that from Google, but Microsoft has some good guidelines for transient fault handling as well as patterns for error handling for resilient applications. Maybe that's what you remember?

It must be it. Do you have the link or do you have tips on how I could find it myself?

https://learn.microsoft.com/en-us/azure/architecture/best-practices/transient-faults
https://learn.microsoft.com/en-us/azure/architecture/framework/resiliency/app-design-error-handling

@cuihtlauac
Copy link
Collaborator Author

Thanks @rikusilvola. It's not what I had in mind. But it's great stuff! I'll see what I can do from there.

cuihtlauac pushed a commit that referenced this pull request Apr 26, 2023
cuihtlauac pushed a commit that referenced this pull request Apr 26, 2023
@Zineb-Ada
Copy link
Contributor

Excellent work, I find it very well explained and the code examples are clearer and more detailed.

@Tchou
Copy link

Tchou commented Apr 26, 2023

(I don't know if this is the right place to give general comments, I can also reply on the discuss post. Also sorry if the points below have been taken into account already).
First, it's great that this tutorial is getting an update! A few high level remarks:

  • Some things have no place in this tutorial, especially if it's aimed at beginners. I would remove the subsection about Obj.magic entirely, you don't even want to mention to beginners that this thing exists. Further, it has nothing to do with exceptions vs monadic style.
  • I would not give an example that Stack_overflow is an exception (hence that you can catch it, you shouldn't).
  • The sections about option and result are really nice
  • I would move the part about (let*) to a dedicated subsection and clearly advertise that this is still a language extension and, although unlikely, its behavior may evolve.
  • It seems unfair to point pros and cons of exceptions at the beginning of their presentation and not do the same for options/results (namely that it incurs the burden of checking/extracting the enclosed value at every step, which may require some boilerplate code). This could then be used to advocate the use of binding operators. I would also mention that it incurs boxing/unboxing values which may come with a runtime cost.
  • w.r.t to code examples, it's ok to give code that, in isolation, does not compile (e.g. because some value is not defined because it was defined three examples above) but syntactically incorrect code such as val Option.map : … will be confusing for beginners that will try to cut and paste it. Maybe in such case, not use a code formatting box but just some tt font ?

cuihtlauac pushed a commit that referenced this pull request Apr 26, 2023
@AshineFoster
Copy link
Contributor

The introduction tells the reader not to use special values for error handling but does not say why. I made a new sample intro that gives a small hint as to the problems with special values.

Error Handling

Ocaml handles errors in several ways. This document presents these different ways,
with the exception of effect handlers introduced in Ocaml 5.

Some languages (C, C++, etc.) returns 'special values' to tell the calling function
that there was an error. For example the C printf function returns a negative
value if it encounters an output error. This style of error handling dictates
the programmer to always be aware of the different 'special values' functions might
return and take full responsibility to carry out an appropriate action. Of course
programmers don't always check the return values with the result being billions
of dollars lost and thousands of persons inconvenienced in certain cases.

Ocaml has three alternative ways to deal with errors:

  1. Exceptions
  2. Option values
  3. Result values.

These three options (:-)) enables an Ocaml program to handle errors in much safer
and more consistent ways compared to C's 'special values'.

@cuihtlauac
Copy link
Collaborator Author

Thanks, @Tchou, for the nice words, this helps. To me, both here and discuss are fine for general comments.

I would remove the subsection about Obj.magic entirely, you don't even want to mention to beginners that this thing exists. Further, it has nothing to do with exceptions vs monadic style.

  • I would not give an example that Stack_overflow is an exception

I believe the initial goal of the document was to address all exceptional circumstances; that's why I felt those topics were needed. However, I share your concerns. Maybe I should add some text saying this is mentioned for completeness but left unexplained. As a beginner, I preferred that over “being left in the dark”.

  • I would move the part about (let*) to a dedicated subsection and clearly advertise that this is still a language extension and, although unlikely, its behavior may evolve.

Agreed, will do

  • It seems unfair to point pros and cons of exceptions at the beginning of their presentation and not do the same for options/results (namely that it incurs the burden of checking/extracting the enclosed value at every step, which may require some boilerplate code). This could then be used to advocate the use of binding operators. I would also mention that it incurs boxing/unboxing values which may come with a runtime cost.

Agreed, will do.

  • w.r.t to code examples, it's ok to give code that, in isolation, does not compile (e.g. because some value is not defined because it was defined three examples above) but syntactically incorrect code such as val Option.map : … will be confusing for beginners that will try to cut and paste it. Maybe in such case, not use a code formatting box but just some tt font ?

There's an open issue on that matter: #961

Since this applies to several tutorials, we'll probably won't fix this in this document, in order to preserve formatting consistency. Hopefully, it will help solve the issue at once for all the documents.

Copy link
Collaborator

@sabine sabine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one remark.

In general, I think it's good to merge and improve incrementally from there on.

@tmattio tmattio added the new-doc Track creation of new content for the OCaml Documentation label Jun 6, 2023
sabine pushed a commit that referenced this pull request Jun 7, 2023
@sabine sabine merged commit 5d3f3ab into main Jun 7, 2023
@sabine sabine deleted the doc-error branch June 7, 2023 08:43
@tmattio tmattio linked an issue Jul 19, 2023 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation new-doc Track creation of new content for the OCaml Documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error Handling

9 participants