ui: Gracefully recover from non-existent DC errors (#11077)
* ui: Gracefully recover from non-existent DC errors This PR fixes what happens in the UI if you try to navigate to a non-existing DC. When we received a 500 error from an API response due to a non-existent DC, previously we would show a 404 error, which is what we were trying to convey. But in the spirit of the UI being a 'thin client', its probably best to just show the 500 error from the API response, which may help folks to debug any issues better. * Automatically set the CONSUL_DATACENTER_LOCAL env var for testing
This commit is contained in:
parent
f8afe3e9db
commit
5da06645b0
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
ui: Gracefully recover from non-existant DC errors
|
||||||
|
```
|
|
@ -0,0 +1,11 @@
|
||||||
|
import Helper from '@ember/component/helper';
|
||||||
|
import { getOwner } from '@ember/application';
|
||||||
|
|
||||||
|
export default class CachedHelper extends Helper {
|
||||||
|
compute([model], hash) {
|
||||||
|
return () => {
|
||||||
|
const container = getOwner(this);
|
||||||
|
return container.lookup(`service:repository/${model}`).cached(hash);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -99,6 +99,13 @@ export default class RepositoryService extends Service {
|
||||||
return this.store.peekRecord(this.getModelName(), id);
|
return this.store.peekRecord(this.getModelName(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cached(params) {
|
||||||
|
const entries = Object.entries(params);
|
||||||
|
return this.store.peekAll(this.getModelName()).filter(item => {
|
||||||
|
return entries.every(([key, value]) => item[key] === value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// @deprecated
|
// @deprecated
|
||||||
findAllByDatacenter(params, configuration = {}) {
|
findAllByDatacenter(params, configuration = {}) {
|
||||||
return this.findAll(...arguments);
|
return this.findAll(...arguments);
|
||||||
|
|
|
@ -58,24 +58,44 @@ as |source|>
|
||||||
|
|
||||||
{{! Make sure we guess and default to the right params when not found }}
|
{{! Make sure we guess and default to the right params when not found }}
|
||||||
{{#let
|
{{#let
|
||||||
(or notfound.dc route.params.dc (env "CONSUL_DATACENTER_LOCAL"))
|
|
||||||
(if (can "use partitions") (or route.params.partition notfound.partition token.Partition 'default') 'default')
|
(if (can "use partitions") (or route.params.partition notfound.partition token.Partition 'default') 'default')
|
||||||
(if (can "use nspaces") (or route.params.nspace notfound.nspace token.Namespace 'default') 'default')
|
(if (can "use nspaces") (or route.params.nspace notfound.nspace token.Namespace 'default') 'default')
|
||||||
as |dc partition nspace|}}
|
as |partition nspace|}}
|
||||||
|
|
||||||
{{! Make sure we have enough to show the app chrome}}
|
{{! Make sure we have enough to show the app chrome}}
|
||||||
{{!FIXME}}
|
{{! Don't show anything until we have a list of DCs }}
|
||||||
{{#if (gt dc.length 0)}}
|
<DataSource
|
||||||
|
@src={{uri '/*/*/*/datacenters'}}
|
||||||
{{! Don't show anything until we have a list of DCs }}
|
as |dcs|>
|
||||||
<DataSource
|
|
||||||
@src={{uri '/*/*/*/datacenters'}}
|
|
||||||
as |dcs|>
|
|
||||||
|
|
||||||
|
{{! Once we have a list of DCs make sure the DC we are asking for exists }}
|
||||||
|
{{! If not use the DC that the UI is running in }}
|
||||||
{{#let
|
{{#let
|
||||||
|
(or
|
||||||
|
|
||||||
|
(get (object-at 0 (cached-model
|
||||||
|
'dc'
|
||||||
|
(hash
|
||||||
|
Name=notfound.dc
|
||||||
|
)
|
||||||
|
)) 'Name')
|
||||||
|
|
||||||
|
(get (object-at 0 (cached-model
|
||||||
|
'dc'
|
||||||
|
(hash
|
||||||
|
Name=route.params.dc
|
||||||
|
)
|
||||||
|
)) 'Name')
|
||||||
|
|
||||||
|
(env "CONSUL_DATACENTER_LOCAL")
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
dcs.data
|
dcs.data
|
||||||
as |dcs|}}
|
|
||||||
{{#if (and dcs nspace partition)}}
|
as |dc dcs|}}
|
||||||
|
|
||||||
|
{{#if (and (gt dc.length 0) dcs nspace partition)}}
|
||||||
|
|
||||||
{{! figure out our current DC and convert it to a model }}
|
{{! figure out our current DC and convert it to a model }}
|
||||||
<DataSource
|
<DataSource
|
||||||
|
@ -133,8 +153,7 @@ as |dcs|}}
|
||||||
</DataSource>
|
</DataSource>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/let}}
|
{{/let}}
|
||||||
</DataSource>
|
</DataSource>
|
||||||
{{/if}}
|
|
||||||
{{/let}}
|
{{/let}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</Route>
|
</Route>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
${
|
${
|
||||||
range(env('CONSUL_DATACENTER_COUNT', 10)).map((item, i) => {
|
range(env('CONSUL_DATACENTER_COUNT', 10)).map((item, i) => {
|
||||||
if(i === 0) {
|
if(i === 0) {
|
||||||
return `"dc1"`;
|
return `"${env('CONSUL_DATACENTER_LOCAL', 'dc1')}"`;
|
||||||
}
|
}
|
||||||
return `
|
return `
|
||||||
"${fake.address.countryCode().toLowerCase()}_${ i % 2 ? "west" : "east"}-${i}"
|
"${fake.address.countryCode().toLowerCase()}_${ i % 2 ? "west" : "east"}-${i}"
|
||||||
|
|
|
@ -23,8 +23,6 @@ Feature: dc / error: Recovering from a dc 500 error
|
||||||
Then the url should be /dc-500/services
|
Then the url should be /dc-500/services
|
||||||
And the title should be "Consul"
|
And the title should be "Consul"
|
||||||
Then I see status on the error like "500"
|
Then I see status on the error like "500"
|
||||||
# FIXME
|
|
||||||
@ignore
|
|
||||||
Scenario: Clicking the back to root button
|
Scenario: Clicking the back to root button
|
||||||
Given the url "/v1/internal/ui/services" responds with a 200 status
|
Given the url "/v1/internal/ui/services" responds with a 200 status
|
||||||
When I click home
|
When I click home
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
@setupApplicationTest
|
@setupApplicationTest
|
||||||
# FIXME
|
|
||||||
@ignore
|
|
||||||
Feature: dc / services / error
|
Feature: dc / services / error
|
||||||
Scenario: Arriving at the service page that doesn't exist
|
Scenario: Arriving at the service page that doesn't exist
|
||||||
Given 2 datacenter models from yaml
|
Given 2 datacenter models from yaml
|
||||||
|
@ -8,11 +6,12 @@ Feature: dc / services / error
|
||||||
- dc-1
|
- dc-1
|
||||||
- dc-2
|
- dc-2
|
||||||
---
|
---
|
||||||
|
Given the url "/v1/internal/ui/services" responds with a 500 status
|
||||||
When I visit the services page for yaml
|
When I visit the services page for yaml
|
||||||
---
|
---
|
||||||
dc: 404-datacenter
|
dc: non-existent-datacenter
|
||||||
---
|
---
|
||||||
Then I see status on the error like "404"
|
Then I see status on the error like "500"
|
||||||
@notNamespaceable
|
@notNamespaceable
|
||||||
Scenario: Arriving at the service page
|
Scenario: Arriving at the service page
|
||||||
Given 2 datacenter models from yaml
|
Given 2 datacenter models from yaml
|
||||||
|
|
|
@ -7,11 +7,17 @@ export default function(scenario, create, set, win = window, doc = document) {
|
||||||
return create(number, model);
|
return create(number, model);
|
||||||
})
|
})
|
||||||
.given(['$number $model model[s]? with the value "$value"'], function(number, model, value) {
|
.given(['$number $model model[s]? with the value "$value"'], function(number, model, value) {
|
||||||
|
if (model === 'dc') {
|
||||||
|
doc.cookie = `CONSUL_DATACENTER_LOCAL=${value}`;
|
||||||
|
}
|
||||||
return create(number, model, value);
|
return create(number, model, value);
|
||||||
})
|
})
|
||||||
.given(
|
.given(
|
||||||
['$number $model model[s]? from yaml\n$yaml', '$number $model model[s]? from json\n$json'],
|
['$number $model model[s]? from yaml\n$yaml', '$number $model model[s]? from json\n$json'],
|
||||||
function(number, model, data) {
|
function(number, model, data) {
|
||||||
|
if (model === 'dc') {
|
||||||
|
doc.cookie = `CONSUL_DATACENTER_LOCAL=${data[0]}`;
|
||||||
|
}
|
||||||
return create(number, model, data);
|
return create(number, model, data);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue