-
Notifications
You must be signed in to change notification settings - Fork 3k
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
fix(errors): Better error message when you return non-observable things, #2152
Conversation
If we can be sure that Edit: subscribeToResult is used by |
@jayphelps, you're one of my favorites <3 |
@kentcdodds hahaha well, I'm sure the others were gonna jump on this too. I literally already had a branch to change this that's been sitting for several months and your issue reminded me to finish. This really is an annoyance I've had to deal with helping others on gitter, etc. |
Yeah, one thing that really helped me with beginner questions on angular-formly was validating every API with |
@kentcdodds Yeah, TS shouldn't let you return non-observable things. We could certainly consider adding more robust error checking wrapped in React-style |
like `undefined` fixes ReactiveX#215
Can definitely create a ticket! |
Could we avoid introducing any code like this that's going to require a specific build process? We have a ton of consumers of Rx not using Webpack, so I'd like to avoid penalizing them. |
Yes, that would be best. Optimally we should probably do what React's done by having the minified version exclude this stuff. So people not using a build system should use the minified version, and people using a build system can remove that themselves as part of the build. I wonder if there's a better way... If I recall correctly, @jmdobry had a |
All that said, one of the drawbacks of doing an "opt-in" system for this kind of thing is the people who generally need this kind of help wont know to opt into the help and you lose one of the main benefits of doing something like this in the first place. I think that making an opt-out version which removes this stuff is better. |
In any case, this is something that'll take a bit of effort, but it's well worth it IMO :) |
@robwormald @kentcdodds agreed. We can continue that discussion in #2153 💃 |
destination.error(new TypeError('unknown type returned')); | ||
const value = isObject(result) ? 'an invalid object' : `'${result}'`; | ||
const msg = `You provided ${value} where a stream was expected.` | ||
+ ' You can provide an Observable, Promise, Array, or Iterable.'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nitpicking, but one could return an Rx.Observable or a "lowercase-o observable" which is any object that implements Symbol.observable
. How do we differentiate those two things there? Maybe Observable, Promise, Array, Iterable or object implementing Symbol.observable
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I just punted on Symbol.observable
because it felt like one of those "if you know it exists, you know it's supported" things. But I'm cool with adding of an object implementing Symbol.observable
destination.error(new TypeError('unknown type returned')); | ||
const value = isObject(result) ? 'an invalid object' : `'${result}'`; | ||
const msg = `You provided ${value} where a stream was expected.` | ||
+ ' You can provide an Observable, Promise, Array, or Iterable.'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, can we just use a single template string \
like this`` here instead of concatenating two strings together? I feel like the newline in the message is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you use template strings, the indention will matter and be wack. I would need to do this:
const msg = `You provided ${value} where a stream was expected.
You can provide an Observable, Promise, Array, or Iterable.`;
// Notice how this can't be indented, otherwise the indention will also transfer through
// e.g. this:
const msg = `You provided ${value} where a stream was expected.
You can provide an Observable, Promise, Array, or Iterable.`;
// would output:
You provided null where a stream was expected.
You can provide an Observable, Promise, Array, or Iterable.
If you're OK with either of these (or something else), I can change it. lmk. I may have to add an eslint ignore line, dunno.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please no. Please, leave it like it is :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it can't be indented. It just seems inefficient to allocate two strings, then concatenate them into another string. I'm okay with breaking the line length linting rule here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then again, check the TypeScript compiled output, maybe if accounts for this and fixes it automagically.
LGTM |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
One thing I thought about doing is having operators (who are the ones who call
subscribeToResult
) pass in the operator name, so that the error message could also say which operator it thinks it occured in. But, what about operator aliases? i.e. mergeMap/flatMap, etc. And also, this could potentially be more confusing if it's a custom operator that calls other operators inside of it--but perhaps that's rare enough in the wild to discount it.So for example:
You provided 'undefined' to 'mergeMap|flatMap' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
Cc/ @kentcdodds