diff --git a/CHANGELOG.md b/CHANGELOG.md index ef889f6d2..a56bcd1c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,14 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Added - Added costs for configurable string feature options in `manifold-plan-selector`. -- Added `read-only` attribute to `manifold-plan-details` to optionally disable inputs for configurable features. +- Added `read-only` attribute to `manifold-plan-details` to optionally disable inputs for + configurable features. - Added the ability to create and resize plans with configurable features. +### Fixed + +- Properly handle errors from aborted network requests in `manifold-plan-cost`. + ## [0.9.3] - 2019-01-13 ### Added diff --git a/package.json b/package.json index 52c0a3501..486cabc99 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@manifoldco/ui", "description": "Manifold UI", - "version": "0.9.3", + "version": "0.9.4-rc.0", "repository": { "type": "git", "url": "git+https://github.com/manifoldco/ui.git" diff --git a/src/components/manifold-plan-cost/manifold-plan-cost.tsx b/src/components/manifold-plan-cost/manifold-plan-cost.tsx index 8ff2df392..f7f0526e2 100644 --- a/src/components/manifold-plan-cost/manifold-plan-cost.tsx +++ b/src/components/manifold-plan-cost/manifold-plan-cost.tsx @@ -20,6 +20,7 @@ export class ManifoldPlanCost { @Prop() selectedFeatures?: Gateway.FeatureMap; @State() calculatedCost?: number; @State() controller?: AbortController; + @State() error?: string; @Watch('plan') planChange() { this.fetchCustomCost(); } @@ -45,6 +46,7 @@ export class ManifoldPlanCost { // Hide display while calculating this.calculatedCost = undefined; + this.error = undefined; if (this.controller) { this.controller.abort(); } // If a request is in flight, cancel it @@ -58,27 +60,42 @@ export class ManifoldPlanCost { planID: this.plan.id, features, init: { signal: this.controller.signal }, - }).then(({ cost }: Gateway.Price) => { - this.calculatedCost = cost || 0; - this.controller = undefined; // Request finished, so signal no longer needed - }); + }) + .then(({ cost }: Gateway.Price) => { + this.calculatedCost = cost || 0; + this.controller = undefined; // Request finished, so signal no longer needed + }) + .catch(e => { + if (e.name !== 'AbortError') { + this.error = 'Error getting plan cost.'; + } + }); } @logger() render() { + if (this.error) { + return {this.error}; + } + + if (this.calculatedCost === undefined) { + return Calculating cost...; + } + + const meteredFeatures = + (this.plan && this.plan.meteredFeatures && this.plan.meteredFeatures.edges) || undefined; + const isConfigurable = + (this.plan && + this.plan.configurableFeatures && + this.plan.configurableFeatures.edges.length > 0) || + false; + return ( 0) || - false - } + meteredFeatures={meteredFeatures} + configurable={isConfigurable} /> ); }