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

Allow propagation of errors from Subscriptions channels into Request.Errs #314

Closed
abourget opened this issue Mar 29, 2019 · 13 comments
Closed

Comments

@abourget
Copy link

Hi there,

From what I can gather in the current source, it's not possible to gather errors that happened on the producer side of the chan that is used to stream subscription responses. Having only a channel, you can write responses, or close the channel. If, while streaming one of the messages, your backend database fails, you can't send a proper error message, saying why you are closing the subscription.

I propose adding an interface, like:

type SubscriptionError interface {
    SubscriptionError() error
}

and if implemented, would be checked before resolving all the fields. If such a function returns an error, then it would be AddError()'d, and return null data immediately.

With such a mechanism, the top-level objects could gather errors in a field on that object before pushing it to the chan, and expose it through SubscriptionError().

Feedback welcome, I was thinking my team could implement it and propose a PR, but wanted to open the discussion first. There are probably two dozens better solutions, please share :)

@abourget abourget changed the title Allow propagation of errors from Subscriptions channels into Response.Errs Allow propagation of errors from Subscriptions channels into Request.Errs Mar 29, 2019
@CreatCodeBuild
Copy link

May you give an example from the user side of the lib?

@abourget
Copy link
Author

abourget commented Apr 5, 2019

Injecting an object in the channel kicks off the Resolver on that object.

At this line: https://github.com/graph-gophers/graphql-go/blob/master/internal/exec/subscribe.go#L101
where the resp object is the received object within graphql-go, we could do a check for the SubscriptionError on resp, and call it if it fails, and return something like:

if err := subscriberErrorObject.SubscriberError(); err != nil {
	c <- &Response{Errors: []*errors.QueryError{errors.Errorf("%s", err)}}
	continue
}

The user would simply need to return an object to be resolved that implements that method, and returns an error object that it has kept within.

Ex:

type Person struct {
    Name string
    Email string
    err error
}
func (p *Person) SubscriptionError() error {
    return err
}

and while fetching that Person, if you get any failure, you can return that in the message you send over... and decide, or not, to close the channel after that error.

This makes it so subscriptions can avoid changing error handling in front-end code: messages always contains errors in the message.

Otherwise, there's no way to specify why you're about to close a subscription.. if something fatal occurred.

Does that make sense?

@pavelnikolov
Copy link
Member

If you treat the errors as any other data in your struct, then why does the library even need to know about this? It'll just be part of the response, right?

@abourget
Copy link
Author

abourget commented May 9, 2019

Because in the subscription code, a Response is crafted passing your object as Data. You can't pass anything for Errors

@pavelnikolov
Copy link
Member

pavelnikolov commented May 9, 2019 via email

@abourget
Copy link
Author

Hmm, not sure I get that. GraphQL already has an error model. I simply want to reuse that. My data model is the same in queries as in subscriptions. I don't want to craft my own custom error handling in my schema. Like a UserWithError type?!

I've never seen an API do that.

@abourget
Copy link
Author

Subscriptions return standard GraphQL responses, composed of a "data" field, and an optional "errors" field, with the structure in the "errors" package (in this repo).

@abourget
Copy link
Author

Check the PR referenced above ^^

@pavelnikolov
Copy link
Member

I'm looking into the PR. I'm sorry I didn't understand the problem earlier.

@pavelnikolov
Copy link
Member

There is a pending conflict and question... 👀

@abourget
Copy link
Author

Sorry for the delay.. I've gone through and tried to address the questions.

I know there are 2 features in there.. tell me what it takes to bring those things in :)

@pavelnikolov
Copy link
Member

As a beginning, send the subscription error propagation first in a separate PR.

@pavelnikolov
Copy link
Member

pavelnikolov commented Mar 7, 2023

@abourget I think that #420 solve this issue, right? And I believe that this unit test demonstrates the ability to propagate subscription errors to the user. Let me know if more documentation is needed to explain this better.

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

No branches or pull requests

3 participants