Skip to content

Commit 9730c0b

Browse files
committed
Auto merge of #2960 - Turbo87:index-error, r=locks
Implement error handling for the index page When an error occurs we display an error message with a "Try Again" button now. <img width="978" alt="Bildschirmfoto 2020-10-25 um 17 09 10" src="https://user-images.githubusercontent.com/141300/97112480-d5c8e700-16e4-11eb-8f27-9ee6d6d9d535.png"> r? `@locks`
2 parents 24dd398 + 6d103dc commit 9730c0b

File tree

7 files changed

+252
-180
lines changed

7 files changed

+252
-180
lines changed

app/controllers/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Controller from '@ember/controller';
2-
import { computed } from '@ember/object';
2+
import { action, computed } from '@ember/object';
33
import { readOnly } from '@ember/object/computed';
44
import { inject as service } from '@ember/service';
55

@@ -15,6 +15,12 @@ export default class IndexController extends Controller {
1515
return this.dataTask.lastSuccessful && !this.dataTask.isRunning;
1616
}
1717

18+
@action fetchData() {
19+
this.dataTask.perform().catch(() => {
20+
// we ignore errors here because they are handled in the template already
21+
});
22+
}
23+
1824
@(task(function* () {
1925
let data = yield this.fetcher.ajax('/api/v1/summary');
2026

app/routes/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default class IndexRoute extends Route {
1818

1919
setupController(controller) {
2020
if (!controller.hasData) {
21-
let promise = controller.dataTask.perform();
21+
let promise = controller.fetchData();
2222
if (this.fastboot.isFastBoot) {
2323
this.fastboot.deferRendering(promise);
2424
}

app/styles/index.module.css

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
.hero-button {
2323
composes: yellow-button from '../styles/shared/buttons.module.css';
24-
vertical-align: initial;
2524

2625
.icon {
2726
color: #c4890e;
@@ -80,3 +79,17 @@
8079
list-style: none;
8180
padding: 0;
8281
}
82+
83+
.error-message {
84+
line-height: 25px;
85+
}
86+
87+
.try-again-button {
88+
composes: yellow-button from './shared/buttons.module.css';
89+
align-self: center;
90+
margin: 20px 0;
91+
92+
.spinner {
93+
margin-left: 7px;
94+
}
95+
}

app/styles/shared/buttons.module.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
--bg-color-bottom-dark: #fdbb39;
2222

2323
padding: 15px 40px;
24-
display: inline-block;
24+
display: inline-flex;
25+
align-items: center;
2526
color: var(--text-color);
2627
text-decoration: none;
2728
font-weight: bold;
@@ -49,7 +50,6 @@
4950

5051
.yellow-button {
5152
composes: button;
52-
vertical-align: middle;
5353
}
5454

5555
.tan-button {

app/templates/index.hbs

Lines changed: 163 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -39,150 +39,171 @@
3939
</div>
4040
</div>
4141

42-
<div local-class='lists'>
43-
<section data-test-new-crates>
44-
<h2>New Crates</h2>
45-
<ol local-class="list" aria-busy="{{this.dataTask.isRunning}}">
46-
{{#if this.dataTask.isRunning}}
47-
{{#each (placeholders 10)}}
48-
<li>
49-
<FrontPageList::Item::Placeholder @withSubtitle={{true}} />
50-
</li>
51-
{{/each}}
52-
{{else}}
53-
{{#each this.model.new_crates as |crate index|}}
54-
<li>
55-
<FrontPageList::Item
56-
@route="crate"
57-
@model={{crate.id}}
58-
@title={{crate.name}}
59-
@subtitle="v{{crate.newest_version}}"
60-
data-test-crate-link={{index}}
61-
/>
62-
</li>
63-
{{/each}}
64-
{{/if}}
65-
</ol>
66-
</section>
42+
{{#if this.dataTask.lastComplete.error}}
43+
<p local-class="error-message" data-test-error-message>
44+
Unfortunately something went wrong while loading the crates.io summary data.
45+
Feel free to try again, or let the <a href="mailto:[email protected]">crates.io
46+
team</a> know if the problem persists.
47+
</p>
6748

68-
<section data-test-most-downloaded>
69-
<h2>Most Downloaded</h2>
70-
<ol local-class="list" aria-busy="{{this.dataTask.isRunning}}">
71-
{{#if this.dataTask.isRunning}}
72-
{{#each (placeholders 10)}}
73-
<li>
74-
<FrontPageList::Item::Placeholder />
75-
</li>
76-
{{/each}}
77-
{{else}}
78-
{{#each this.model.most_downloaded as |crate index|}}
79-
<li>
80-
<FrontPageList::Item
81-
@route="crate"
82-
@model={{crate.id}}
83-
@title={{crate.name}}
84-
data-test-crate-link={{index}}
85-
/>
86-
</li>
87-
{{/each}}
88-
{{/if}}
89-
</ol>
90-
</section>
49+
<button
50+
type="button"
51+
disabled={{this.dataTask.isRunning}}
52+
local-class="try-again-button"
53+
data-test-try-again-button
54+
{{on "click" this.fetchData}}
55+
>
56+
Try Again
57+
{{#if this.dataTask.isRunning}}
58+
<LoadingSpinner local-class="spinner" data-test-spinner />
59+
{{/if}}
60+
</button>
61+
{{else}}
62+
<div local-class='lists' data-test-lists>
63+
<section data-test-new-crates>
64+
<h2>New Crates</h2>
65+
<ol local-class="list" aria-busy="{{this.dataTask.isRunning}}">
66+
{{#if this.dataTask.isRunning}}
67+
{{#each (placeholders 10)}}
68+
<li>
69+
<FrontPageList::Item::Placeholder @withSubtitle={{true}} />
70+
</li>
71+
{{/each}}
72+
{{else}}
73+
{{#each this.model.new_crates as |crate index|}}
74+
<li>
75+
<FrontPageList::Item
76+
@route="crate"
77+
@model={{crate.id}}
78+
@title={{crate.name}}
79+
@subtitle="v{{crate.newest_version}}"
80+
data-test-crate-link={{index}}
81+
/>
82+
</li>
83+
{{/each}}
84+
{{/if}}
85+
</ol>
86+
</section>
9187

92-
<section data-test-just-updated>
93-
<h2>Just Updated</h2>
94-
<ol local-class="list" aria-busy="{{this.dataTask.isRunning}}">
95-
{{#if this.dataTask.isRunning}}
96-
{{#each (placeholders 10)}}
97-
<li>
98-
<FrontPageList::Item::Placeholder @withSubtitle={{true}} />
99-
</li>
100-
{{/each}}
101-
{{else}}
102-
{{#each this.model.just_updated as |crate index|}}
103-
<li>
104-
<FrontPageList::Item
105-
@route="crate"
106-
@model={{crate.id}}
107-
@title={{crate.name}}
108-
@subtitle="v{{crate.newest_version}}"
109-
data-test-crate-link={{index}}
110-
/>
111-
</li>
112-
{{/each}}
113-
{{/if}}
114-
</ol>
115-
</section>
88+
<section data-test-most-downloaded>
89+
<h2>Most Downloaded</h2>
90+
<ol local-class="list" aria-busy="{{this.dataTask.isRunning}}">
91+
{{#if this.dataTask.isRunning}}
92+
{{#each (placeholders 10)}}
93+
<li>
94+
<FrontPageList::Item::Placeholder />
95+
</li>
96+
{{/each}}
97+
{{else}}
98+
{{#each this.model.most_downloaded as |crate index|}}
99+
<li>
100+
<FrontPageList::Item
101+
@route="crate"
102+
@model={{crate.id}}
103+
@title={{crate.name}}
104+
data-test-crate-link={{index}}
105+
/>
106+
</li>
107+
{{/each}}
108+
{{/if}}
109+
</ol>
110+
</section>
116111

117-
<section data-test-most-recently-downloaded>
118-
<h2>Most Recent Downloads</h2>
119-
<ol local-class="list" aria-busy="{{this.dataTask.isRunning}}">
120-
{{#if this.dataTask.isRunning}}
121-
{{#each (placeholders 10)}}
122-
<li>
123-
<FrontPageList::Item::Placeholder />
124-
</li>
125-
{{/each}}
126-
{{else}}
127-
{{#each this.model.most_recently_downloaded as |crate index|}}
128-
<li>
129-
<FrontPageList::Item
130-
@route="crate"
131-
@model={{crate.id}}
132-
@title={{crate.name}}
133-
data-test-crate-link={{index}}
134-
/>
135-
</li>
136-
{{/each}}
137-
{{/if}}
138-
</ol>
139-
</section>
112+
<section data-test-just-updated>
113+
<h2>Just Updated</h2>
114+
<ol local-class="list" aria-busy="{{this.dataTask.isRunning}}">
115+
{{#if this.dataTask.isRunning}}
116+
{{#each (placeholders 10)}}
117+
<li>
118+
<FrontPageList::Item::Placeholder @withSubtitle={{true}} />
119+
</li>
120+
{{/each}}
121+
{{else}}
122+
{{#each this.model.just_updated as |crate index|}}
123+
<li>
124+
<FrontPageList::Item
125+
@route="crate"
126+
@model={{crate.id}}
127+
@title={{crate.name}}
128+
@subtitle="v{{crate.newest_version}}"
129+
data-test-crate-link={{index}}
130+
/>
131+
</li>
132+
{{/each}}
133+
{{/if}}
134+
</ol>
135+
</section>
140136

141-
<section data-test-keywords>
142-
<h2>Popular Keywords <LinkTo @route="keywords">(see all)</LinkTo></h2>
143-
<ul local-class="list" aria-busy="{{this.dataTask.isRunning}}">
144-
{{#if this.dataTask.isRunning}}
145-
{{#each (placeholders 10)}}
146-
<li>
147-
<FrontPageList::Item::Placeholder @withSubtitle={{true}} />
148-
</li>
149-
{{/each}}
150-
{{else}}
151-
{{#each this.model.popular_keywords as |keyword|}}
152-
<li>
153-
<FrontPageList::Item
154-
@route="keyword"
155-
@model={{keyword}}
156-
@title={{keyword.id}}
157-
@subtitle="{{format-num keyword.crates_cnt}} crates"
158-
/>
159-
</li>
160-
{{/each}}
161-
{{/if}}
162-
</ul>
163-
</section>
137+
<section data-test-most-recently-downloaded>
138+
<h2>Most Recent Downloads</h2>
139+
<ol local-class="list" aria-busy="{{this.dataTask.isRunning}}">
140+
{{#if this.dataTask.isRunning}}
141+
{{#each (placeholders 10)}}
142+
<li>
143+
<FrontPageList::Item::Placeholder />
144+
</li>
145+
{{/each}}
146+
{{else}}
147+
{{#each this.model.most_recently_downloaded as |crate index|}}
148+
<li>
149+
<FrontPageList::Item
150+
@route="crate"
151+
@model={{crate.id}}
152+
@title={{crate.name}}
153+
data-test-crate-link={{index}}
154+
/>
155+
</li>
156+
{{/each}}
157+
{{/if}}
158+
</ol>
159+
</section>
164160

165-
<section data-test-categories>
166-
<h2>Popular Categories <LinkTo @route="categories">(see all)</LinkTo></h2>
167-
<ul local-class="list" aria-busy="{{this.dataTask.isRunning}}">
168-
{{#if this.dataTask.isRunning}}
169-
{{#each (placeholders 10)}}
170-
<li>
171-
<FrontPageList::Item::Placeholder @withSubtitle={{true}} />
172-
</li>
173-
{{/each}}
174-
{{else}}
175-
{{#each this.model.popular_categories as |category|}}
176-
<li>
177-
<FrontPageList::Item
178-
@route="category"
179-
@model={{category.slug}}
180-
@title={{category.category}}
181-
@subtitle="{{format-num category.crates_cnt}} crates"
182-
/>
183-
</li>
184-
{{/each}}
185-
{{/if}}
186-
</ul>
187-
</section>
188-
</div>
161+
<section data-test-keywords>
162+
<h2>Popular Keywords <LinkTo @route="keywords">(see all)</LinkTo></h2>
163+
<ul local-class="list" aria-busy="{{this.dataTask.isRunning}}">
164+
{{#if this.dataTask.isRunning}}
165+
{{#each (placeholders 10)}}
166+
<li>
167+
<FrontPageList::Item::Placeholder @withSubtitle={{true}} />
168+
</li>
169+
{{/each}}
170+
{{else}}
171+
{{#each this.model.popular_keywords as |keyword|}}
172+
<li>
173+
<FrontPageList::Item
174+
@route="keyword"
175+
@model={{keyword}}
176+
@title={{keyword.id}}
177+
@subtitle="{{format-num keyword.crates_cnt}} crates"
178+
/>
179+
</li>
180+
{{/each}}
181+
{{/if}}
182+
</ul>
183+
</section>
184+
185+
<section data-test-categories>
186+
<h2>Popular Categories <LinkTo @route="categories">(see all)</LinkTo></h2>
187+
<ul local-class="list" aria-busy="{{this.dataTask.isRunning}}">
188+
{{#if this.dataTask.isRunning}}
189+
{{#each (placeholders 10)}}
190+
<li>
191+
<FrontPageList::Item::Placeholder @withSubtitle={{true}} />
192+
</li>
193+
{{/each}}
194+
{{else}}
195+
{{#each this.model.popular_categories as |category|}}
196+
<li>
197+
<FrontPageList::Item
198+
@route="category"
199+
@model={{category.slug}}
200+
@title={{category.category}}
201+
@subtitle="{{format-num category.crates_cnt}} crates"
202+
/>
203+
</li>
204+
{{/each}}
205+
{{/if}}
206+
</ul>
207+
</section>
208+
</div>
209+
{{/if}}

0 commit comments

Comments
 (0)