Open richard-cox opened 2 months ago
We are pushing this issue out because it appears to be more complex than originally thought. A few discoveries:
"[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core
at <Index class="outlet" onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
at <RouterView key="/c/_/manager/cloudCredential" class="outlet" >
at <Default onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy(Object) {_fetchDelay: 200, $fetch: ƒ, updatePageActions: ƒ, setCustomColor: ƒ, removeCustomColor: ƒ, …} > >
at <RouterView key=1 >
at <App>"
This can be reproduced by throwing an error inside data in 'shell/pages/c/_cluster/manager/cloudCredential/index.vue'
Some suggestions: https://github.com/rancher/dashboard/pull/12198
We should strongly consider refactoring instances of data that contain complex initialization logic. The project will benefit from writing idiomatic Vue code, and my concern is that we're trying to preserve an anti-pattern instead of correcting and discouraging its usage.
We can eliminate this problem entirely by moving logic and side effects to lifecycle hooks, computed props, or methods and keeping data
simple and focused on initializing reactive state.
@rak-phillip If the anti-pattern was just tech debt i would agree. This issue though is about ensuring the ui doesn't 'crash' (show a blank page, require refresh), which is about worst thing that can happen, erodes faith in the product and rancher, and is a vue3 UX regression.
Once we identify places where this covers we can address in a better, targeted way (whilst still incrementally converting the complex data fn's over to something better).
In that case, I'd like to advocate for guarding against as many critical failures as possible for 2.10.
A straightforward way to address this is to wrap each offending instance of complex initialization in data in a try..catch
block, handle the error ourselves, and allow Vue to return some data object (closer to the Vue2 behavior). It's not elegant, but it limits the scope for potential failures and erosion of trust.
If we consider all components that contain a data prop that does not immediately return an object
data () {
return {
These can be interpreted as containing complex initialization logic; we would have at least 155 components to cover:
grep -rPzol -C 5 "data\s*\(\)\s*{(?![^{]*return\s*{)" --exclude-dir node_modules --include="*.vue" .
``` ./pkg/aks/components/Taint.vue ./pkg/harvester-manager/machine-config/harvester.vue ./shell/chart/monitoring/grafana/index.vue ./shell/chart/istio.vue ./shell/cloud-credential/generic.vue ./shell/cloud-credential/azure.vue ./shell/components/EmberPageView.vue ./shell/components/Questions/Reference.vue ./shell/components/ResourceList/Masthead.vue ./shell/components/ResourceList/index.vue ./shell/components/SortableTable/index.vue ./shell/components/fleet/FleetIntro.vue ./shell/components/fleet/FleetNoWorkspaces.vue ./shell/components/form/ResourceQuota/Project.vue ./shell/components/form/Command.vue ./shell/components/form/EnvVars.vue ./shell/components/form/HealthCheck.vue ./shell/components/form/HookOption.vue ./shell/components/form/LifecycleHooks.vue ./shell/components/form/MatchExpressions.vue ./shell/components/form/NameNsDescription.vue ./shell/components/form/Networking.vue ./shell/components/form/NodeAffinity.vue ./shell/components/form/NodeScheduling.vue ./shell/components/form/PodAffinity.vue ./shell/components/form/Probe.vue ./shell/components/form/ResourceSelector.vue ./shell/components/form/ShellInput.vue ./shell/components/form/Tolerations.vue ./shell/components/form/ValueFromResource.vue ./shell/components/form/WorkloadPorts.vue ./shell/components/form/ArrayList.vue ./shell/components/form/Security.vue ./shell/components/formatter/ExtensionCache.vue ./shell/components/formatter/Port.vue ./shell/components/formatter/SecretData.vue ./shell/components/formatter/SecretType.vue ./shell/components/formatter/ServiceType.vue ./shell/components/nav/TopLevelMenu.vue ./shell/components/AlertTable.vue ./shell/components/ContainerResourceLimit.vue ./shell/components/HarvesterServiceAddOnConfig.vue ./shell/components/PromptRemove.vue ./shell/components/ResourceYaml.vue ./shell/components/YamlEditor.vue ./shell/detail/management.cattle.io.user.vue ./shell/detail/namespace.vue ./shell/detail/secret.vue ./shell/detail/service.vue ./shell/edit/auth/ldap/config.vue ./shell/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue ./shell/edit/autoscaling.horizontalpodautoscaler/metric-target.vue ./shell/edit/constraints.gatekeeper.sh.constraint/index.vue ./shell/edit/logging-flow/index.vue ./shell/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue ./shell/edit/logging.banzaicloud.io.output/providers/gelf.vue ./shell/edit/logging.banzaicloud.io.output/providers/opensearch.vue ./shell/edit/logging.banzaicloud.io.output/providers/redis.vue ./shell/edit/logging.banzaicloud.io.output/providers/syslog.vue ./shell/edit/logging.banzaicloud.io.output/index.vue ./shell/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue ./shell/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue ./shell/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue ./shell/edit/monitoring.coreos.com.alertmanagerconfig/auth.vue ./shell/edit/monitoring.coreos.com.alertmanagerconfig/index.vue ./shell/edit/monitoring.coreos.com.alertmanagerconfig/tls.vue ./shell/edit/monitoring.coreos.com.receiver/types/opsgenie.vue ./shell/edit/monitoring.coreos.com.receiver/types/pagerduty.vue ./shell/edit/monitoring.coreos.com.receiver/types/slack.vue ./shell/edit/monitoring.coreos.com.receiver/types/webhook.vue ./shell/edit/monitoring.coreos.com.receiver/auth.vue ./shell/edit/monitoring.coreos.com.receiver/index.vue ./shell/edit/monitoring.coreos.com.receiver/tls.vue ./shell/edit/networking.istio.io.destinationrule/LoadBalancer.vue ./shell/edit/networking.k8s.io.ingress/Certificate.vue ./shell/edit/networking.k8s.io.ingress/Rule.vue ./shell/edit/networking.k8s.io.ingress/RulePath.vue ./shell/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue ./shell/edit/networking.k8s.io.networkpolicy/PolicyRules.vue ./shell/edit/networking.k8s.io.networkpolicy/index.vue ./shell/edit/persistentvolume/plugins/awsElasticBlockStore.vue ./shell/edit/persistentvolume/plugins/azureDisk.vue ./shell/edit/persistentvolume/plugins/azureFile.vue ./shell/edit/persistentvolume/plugins/cephfs.vue ./shell/edit/persistentvolume/plugins/cinder.vue ./shell/edit/persistentvolume/plugins/csi.vue ./shell/edit/persistentvolume/plugins/fc.vue ./shell/edit/persistentvolume/plugins/flexVolume.vue ./shell/edit/persistentvolume/plugins/flocker.vue ./shell/edit/persistentvolume/plugins/gcePersistentDisk.vue ./shell/edit/persistentvolume/plugins/glusterfs.vue ./shell/edit/persistentvolume/plugins/hostPath.vue ./shell/edit/persistentvolume/plugins/iscsi.vue ./shell/edit/persistentvolume/plugins/local.vue ./shell/edit/persistentvolume/plugins/longhorn.vue ./shell/edit/persistentvolume/plugins/nfs.vue ./shell/edit/persistentvolume/plugins/photonPersistentDisk.vue ./shell/edit/persistentvolume/plugins/portworxVolume.vue ./shell/edit/persistentvolume/plugins/quobyte.vue ./shell/edit/persistentvolume/plugins/rbd.vue ./shell/edit/persistentvolume/plugins/scaleIO.vue ./shell/edit/persistentvolume/plugins/storageos.vue ./shell/edit/persistentvolume/plugins/vsphereVolume.vue ./shell/edit/persistentvolume/index.vue ./shell/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue ./shell/edit/provisioning.cattle.io.cluster/tabs/networking/ACE.vue ./shell/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue ./shell/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue ./shell/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions.vue ./shell/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue ./shell/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue ./shell/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue ./shell/edit/provisioning.cattle.io.cluster/rke2.vue ./shell/edit/secret/index.vue ./shell/edit/secret/registry.vue ./shell/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/aws-ebs.vue ./shell/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/azure-disk.vue ./shell/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/gce-pd.vue ./shell/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/vsphere-volume.vue ./shell/edit/storage.k8s.io.storageclass/provisioners/driver.longhorn.io.vue ./shell/edit/storage.k8s.io.storageclass/index.vue ./shell/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue ./shell/edit/workload/Job.vue ./shell/edit/workload/Upgrading.vue ./shell/edit/cis.cattle.io.clusterscanbenchmark.vue ./shell/edit/cis.cattle.io.clusterscanprofile.vue ./shell/edit/configmap.vue ./shell/edit/fleet.cattle.io.gitrepo.vue ./shell/edit/helm.cattle.io.projecthelmchart.vue ./shell/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue ./shell/edit/management.cattle.io.fleetworkspace.vue ./shell/edit/management.cattle.io.project.vue ./shell/edit/namespace.vue ./shell/edit/persistentvolumeclaim.vue ./shell/edit/policy.poddisruptionbudget.vue ./shell/edit/resources.cattle.io.restore.vue ./shell/edit/service.vue ./shell/edit/token.vue ./shell/edit/resources.cattle.io.backup.vue ./shell/list/workload.vue ./shell/machine-config/digitalocean.vue ./shell/machine-config/vmwarevsphere.vue ./shell/pages/auth/login.vue ./shell/pages/auth/verify.vue ./shell/pages/c/_cluster/apps/charts/install.vue ./shell/pages/c/_cluster/auth/config/index.vue ./shell/pages/c/_cluster/explorer/EventsTable.vue ./shell/pages/c/_cluster/monitoring/monitor/_namespace/_id.vue ./shell/pages/c/_cluster/monitoring/monitor/create.vue ./shell/pages/c/_cluster/monitoring/route-receiver/_id.vue ./shell/pages/c/_cluster/monitoring/route-receiver/create.vue ./shell/pages/c/_cluster/uiplugins/CatalogList/index.vue ./shell/pages/diagnostic.vue ./shell/pages/fail-whale.vue ./shell/pages/home.vue ```
We can also use this list as potential candidates for refactoring.
Setup
Describe the bug
To Reproduce
data
function, for example/shell/pages/home.vue
Result
Expected Result
Additional Information