Skip to content
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 generic %Meeseeks.Error{} struct #38

Closed
mischov opened this issue May 15, 2018 · 1 comment
Closed

Add generic %Meeseeks.Error{} struct #38

mischov opened this issue May 15, 2018 · 1 comment

Comments

@mischov
Copy link
Owner

mischov commented May 15, 2018

Problem

Meeseeks has no cohesive strategy for errors: in various places {:error, reason_string} or :error may be returned, while in others RuntimeErrors or ArgumentErrors or various custom meeseeks exception types may be raised.

This lack of cohesive strategy leaves users shouldering the burden of discovering and accounting for these various errors, and leaves many errors not providing user-friendly feedback.

Solution

Inspired by @michalmuskala's excellent blog post on errors, I will introduce a generic %Meeseeks.Error{} struct that will extend the Exception behaviour and provide a unified target for all the various library errors.

This error can then be returned in {:error, %Meeseeks.Error{}} tuples, or raised.

My personal experience suggests that this kind of error struct provides the best intersection of ease-of-use and flexibility for use in pattern matching situations like case or with, while also making it easier to provide user-friendly feedback.

Implementation

The %Meeseeks.Error{} struct will contain three fields, :type, :reason, and metadata:

  • type is an atom classifying the general context the error exists in, such as :parser.

  • reason is an atom classifying the general problem, such as :invalid_input.

  • metadata is a map containing any additional information useful for debugging the error, such as %{input: "..."}.

Meeseeks.Error will also implement the Exception behaviour, meaning that it can be raised, and will provide useful error messages.

A Meeseeks.Error.list_errors/0 function will be provided that will list a mapping of error types to reasons for all possible Meeseeks.Errors.

Because returned / raised types are changing, this will be a breaking change

Example

Issue #36 contains this code

with(qt when qt != nil <- Meeseeks.one(doc, css(".qt"))) do

Using a forthcoming Meeseeks.fetch_one function and Meeseeks.Error, this is how a user might rewrite this code

with({:ok, qt} <- Meeseeks.fetch_one(doc, css(".qt"))) do
  ...
else
  {:error, %Meeseeks.Error{type: :select, reason: :no_match}} ->
    ...
end
@mischov
Copy link
Owner Author

mischov commented May 15, 2018

Released in v0.9.0.

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

No branches or pull requests

1 participant