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 error handling when sources fail to load data #41

Merged
merged 2 commits into from
Jul 23, 2018

Conversation

seddy
Copy link
Contributor

@seddy seddy commented Jul 20, 2018

I'm raising this following an initial PR (#39) a couple of weeks ago. I've had a couple of other guys take a look internally before raising and so hopefully it should pretty much be there 🤞. I ended up implementing all three ways mentioned in #39 (as this was trivial in the end; see the do_get/2 method). Happy to make changes, rename stuff etc if you want 😄!

Previously, if any errors occurred when a source tried to load data,
this would get logged and a nil would get returned.

The danger of this is that this means errors may go unnoticed in
production environments (e.g. timeouts to third parties) as a nil
result may be a reasonable one depending on the Source and data.

This provides two additional configurable methods of error handling:

  • :raise_on_error - this will raise a Datlaoader.GetError when one
    of the get methods are called. This is now the default behaviour
    for handling errors
  • :tuples - this changes the get/4/get_many/4 methods to return
    :ok/:error tuples instead of just the value. This frees up the
    caller to handle errors any way they see fit

Previously, if any errors occurred when a source tried to load data,
this would get logged and a `nil` would get returned.

The danger of this is that this means errors may go unnoticed in
production environments (e.g. timeouts to third parties) as a `nil`
result may be a reasonable one depending on the `Source` and data.

This provides two additional configurable methods of error handling:

* `:raise_on_error` - this will raise a `Datlaoader.GetError` when one
  of the `get` methods are called. This is now the default behaviour
  for handling errors
* `:tuples` - this changes the `get/4`/`get_many/4` methods to return
  `:ok`/`:error` tuples instead of just the value. This frees up the
  caller to handle errors any way they see fit
Copy link
Contributor

@benwilson512 benwilson512 left a comment

Choose a reason for hiding this comment

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

This looks really good. I need to look over the test cases a bit more just to make sure that all the bases are covered. Really appreciate this!

file, e.g. to configure it to return nil on error:

config :dataloader,
get_policy: :return_nil_on_error
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not entirely sure top level config makes sense here.

@type source_name :: any

@default_timeout 15_000
def default_timeout, do: @default_timeout

@default_get_policy Application.get_env(:dataloader, :get_policy, :raise_on_error)
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah so this pattern can lead to some fun behaviour for users. They'll do something like:

config :dataloader, get_policy: :return_nil_on_error

and then build their project from scratch. Then they change their mind and remove it. the @default_get_policy value will stay the same. The value was pulled when the dependency was compiled, and the dependency will not be recompiled just because the config changed.

If we're going to accept a mix config option here we need to always retrieve it at runtime.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's an absolutely fair point! I have been burned by that a couple of times before and clearly haven't learned my lesson.

I think you're right though, having this global config isn't really necessary so I'll just remove it 👍

@seddy
Copy link
Contributor Author

seddy commented Jul 23, 2018

@benwilson512 - thanks for the feedback! As suggested I've removed the global configuration for the get_policy, let me know if there's anything else you'd like me to do on this 😄

@benwilson512 benwilson512 merged commit 9f3c4b8 into absinthe-graphql:master Jul 23, 2018
@benwilson512
Copy link
Contributor

This looks great, thank you!

@oneKelvinSmith
Copy link

💯

@seddy
Copy link
Contributor Author

seddy commented Jul 23, 2018

Also, just realised I forgot to mention in the description but many thanks to @oneKelvinSmith who paired with me on this change 👍

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.

3 participants