-
Notifications
You must be signed in to change notification settings - Fork 668
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
createLocalVue errorHandler Option #1670
createLocalVue errorHandler Option #1670
Conversation
Rename createLocalVue to _createLocalVue to indicate private use
Allow VueConfig to be passed in via createLocalVue to be registered on the created vue instance
add findAllParentInstances method to traverse a component's parent to find globally registered properties via createLocalVue
Pass localVue into mounted createLocalVue to register localVue properties on component
Call the user defined errorHandler created on the localVue instance via createLocalVue. This is called in the VTU global error handler
add tests to createLocalVue errorHandler to test invocation on sync and async throws
Wrap async error test for createLocalVue errorHandler in try/finally to prevent global errors
Add additional type safety to find and error for older versions of vue that might propagate a vm value of null/undefined
const error = | ||
typeof errorOrString === 'object' ? errorOrString : new Error(errorOrString) | ||
|
||
// If a user defined errorHandler was register via createLocalVue | ||
// find and call the user defined errorHandler | ||
const instancedErrorHandlers = findAllParentInstances(vm) |
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.
maybe just move this into line 21
that already has the conditional check? A lot of the type checking is for older versions of Vue
export function findAllParentInstances(childVm: any) { | ||
const instances = [childVm] | ||
|
||
function getParent(_vm) { |
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.
Any ideas on how to avoid the closure here?
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.
This is to find the highest Vue
with the custom errorHandler
right? I somehow thought it would "just work" and we wouldn't need to reverse-traverse all the way up. I don't have another way to do this.
I think having the conditional is fine, no problem from my point of view
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.
@lmiller1990 correct. I thought it would work straight out of the box as well, but not exactly for reasons I am having trouble remembering. I want to say it has to do with how the vue instances behave on the component, but don't take my word for it 😅
instance.config = cloneDeep(Vue.config) | ||
|
||
// if a user defined errorHandler is defined by a localVue instance via createLocalVue, register it | ||
instance.config.errorHandler = config.errorHandler || Vue.config.errorHandler |
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.
This is the only line that has changed within the logic, IE adding config.errorHandler
. If we do not feel confortable reviewing this due to scope of change, we can break out the shared
move in a separate PR to more clearly see the change set
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.
shared is private anyway, this should be fine
*/ | ||
function _createLocalVue( | ||
_Vue: Component = Vue, | ||
config: VueConfig = {} |
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.
added argument config: VueConfig = {}
Hi! This is a pretty large PR, please give me the weekend to review. I am excited for this feature. |
@lmiller1990 sure thing! I am excited about it too. Definitely no rush on review as we want to be thorough. What we can do, since this is a fairly large PR where the change set is a bit difficult to determine, is break this out into 2 separate PRs: 1st PR (break out 48f1c14 2nd (implement the I think this would be much easier to review as well as add confidence to what we are doing. What do you think? |
I am happy to review a big PR, no dramas there. |
@lmiller1990 OK cool! I just want to make it as easy as possible and willing to accommodate 😃 |
Sorry about the wait, I have a day off work this week to work on OSS (mainly VTU stuff). I will review/merge and plan release 1.1 for this weekend. |
@lmiller1990 no worries! Let me know if there is anything I can do to help. |
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.
Looks fine to me - this was a ton of work! Great job. I wonder if this will be easier to do in VTU next. I was not expecting this to be so complicated (I don't think you were, either).
// e.g. router-link are created using the correct base constructor | ||
instance.options._base = instance | ||
|
||
// compat for vue-router < 2.7.1 where it does not allow multiple installs |
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.
nice job, this must have been a huge pain to figure out
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.
oh, it was moved here from somewhere else - even better, that means it's been battle tested
instance.config = cloneDeep(Vue.config) | ||
|
||
// if a user defined errorHandler is defined by a localVue instance via createLocalVue, register it | ||
instance.config.errorHandler = config.errorHandler || Vue.config.errorHandler |
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.
shared is private anyway, this should be fine
export function findAllParentInstances(childVm: any) { | ||
const instances = [childVm] | ||
|
||
function getParent(_vm) { |
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.
This is to find the highest Vue
with the custom errorHandler
right? I somehow thought it would "just work" and we wouldn't need to reverse-traverse all the way up. I don't have another way to do this.
I think having the conditional is fine, no problem from my point of view
@lmiller1990 Thanks! Yeah... this was a lot more involved than I thought it would be 😅 . The first approach I took failed miserably 😆 . This seemed to be the way to get the behavior we need with the least amount of change (even though significant change was needed). I will say this is WAYYYY easier with VTU Next. This is what it looks like in VTU Next, which works exactly like you would expect it to 🙂 . |
Oh yeah. Forgot about that thread in VTU next. Anyway, I released 1.1.0, thanks for your help! Pretty significant release. |
Shouldn't |
Because this, I can not test errorHandler by Typescript. |
I don't know what you mean, but if you'd like to improve the types, please make a PR. Alternatively, if you don't know how to fix them, you can open an issue sharing the problem you are having. Thanks! |
@lmiller1990 I think it just need to fix the type file, I wanted to make a PR, |
@lmiller1990 It turned out to be Fork first and then create a pull request. |
The purpose of this PR is to allow an
errorHandler
option forcreateLocalVue
. The goal is to support an interface to allow for support over time as needed for Vue Global Config options.createLocalVue
used to take a private argument, which was a vue instance. The public API does not use this_vue
instance argument, butserver-test-utils
andtest-utils
both do. The first step to supporting this signature was to movecreate-local-vue
to theshared
directory and use the semantic_createLocalVue
when referencing internally. The "new"createLocalVue
(part of the public api) just wraps this by passing throughundefined
to get the default behavior as well as the propagatedVueConfig
.It is worth noting that the VTU behavior for disallowing a global error handler is still valid. The way this feature works is by invoking the registered
errorHandler
in the VTU global error handler before throwing the error. The function traverses the components$parent
up the tree, finds if a localVue instance exists, and if so, invoke theerrorHandler
option if one is defined. That can be seen here. The user definederrorHandler
passed intolocalVue
can also throw an error if desired, but is not recommended.What kind of change does this PR introduce? (check at least one)
Does this PR introduce a breaking change? (check one)
If yes, please describe the impact and migration path for existing applications:
The PR fulfills these requirements:
dev
branch.fix #xxx[,#xxx]
, where "xxx" is the issue number)If adding a new feature, the PR's description includes:
Other information: