Skip to content

Commit ab085a8

Browse files
committed
Show "Retry" button for README loading errors
1 parent 16e5279 commit ab085a8

File tree

5 files changed

+49
-2
lines changed

5 files changed

+49
-2
lines changed

app/controllers/crate/version.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default class CrateVersionController extends Controller {
4343
: await version.loadReadmeTask.perform();
4444

4545
// If the README contains `language-mermaid` we ensure that the `mermaid` library has loaded before we continue
46-
if (readme.includes('language-mermaid') && !this.mermaid.loadTask.lastSuccessful?.value) {
46+
if (readme && readme.includes('language-mermaid') && !this.mermaid.loadTask.lastSuccessful?.value) {
4747
try {
4848
await this.mermaid.loadTask.perform();
4949
} catch (error) {

app/models/version.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ export default class Version extends Model {
122122
loadReadmeTask = keepLatestTask(async () => {
123123
if (this.readme_path) {
124124
let response = await fetch(this.readme_path);
125+
if (response.status === 404 || response.status === 403) {
126+
return;
127+
}
128+
125129
if (!response.ok) {
126130
throw new Error(`README request for ${this.crateName} v${this.num} failed`);
127131
}

app/styles/crate/version.module.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
}
2626
}
2727

28-
.no-readme {
28+
.no-readme, .readme-error {
2929
padding: var(--space-l) var(--space-s);
3030
text-align: center;
3131
font-size: 20px;
@@ -39,6 +39,13 @@
3939
}
4040
}
4141

42+
.retry-button {
43+
composes: yellow-button from '../shared/buttons.module.css';
44+
display: block;
45+
text-align: center;
46+
margin: var(--space-s) auto 0;
47+
}
48+
4249
.placeholder-title {
4350
width: 30%;
4451
height: 25px;

app/templates/crate/version.hbs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@
2525
<article aria-label="Readme" data-test-readme>
2626
<RenderedHtml @html={{this.readme}} local-class="readme" />
2727
</article>
28+
{{else if this.loadReadmeTask.last.error}}
29+
<div local-class="readme-error" data-test-readme-error>
30+
Failed to load <code>README</code> file for {{this.crate.name}} v{{this.currentVersion.num}}
31+
32+
<button
33+
type="button"
34+
local-class="retry-button"
35+
data-test-retry-button
36+
{{on "click" (perform this.loadReadmeTask)}}
37+
>
38+
Retry
39+
</button>
40+
</div>
2841
{{else}}
2942
<div local-class="no-readme" data-test-no-readme>
3043
{{this.crate.name}} v{{this.currentVersion.num}} appears to have no <code>README.md</code> file

tests/acceptance/readme-rendering-test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { click } from '@ember/test-helpers';
12
import { module, test } from 'qunit';
23

34
import percySnapshot from '@percy/ember';
5+
import { Response } from 'miragejs';
46

57
import { setupApplicationTest } from 'crates-io/tests/helpers';
68

@@ -112,4 +114,25 @@ module('Acceptance | README rendering', function (hooks) {
112114
await visit('/crates/serde');
113115
assert.dom('[data-test-no-readme]').exists();
114116
});
117+
118+
test('it shows a fallback if no readme is available2', async function (assert) {
119+
let crate = this.server.create('crate', { name: 'serde' });
120+
this.server.create('version', { crate, num: '1.0.0' });
121+
122+
// Simulate a server error when fetching the README
123+
this.server.get('/api/v1/crates/:name/:version/readme', {}, 500);
124+
125+
await visit('/crates/serde');
126+
assert.dom('[data-test-readme-error]').exists();
127+
assert.dom('[data-test-retry-button]').exists();
128+
129+
// Simulate a successful response when fetching the README
130+
this.server.get(
131+
'/api/v1/crates/:name/:version/readme',
132+
() => new Response(200, { 'Content-Type': 'text/html' }, 'foo'),
133+
);
134+
135+
await click('[data-test-retry-button]');
136+
assert.dom('[data-test-readme]').hasText('foo');
137+
});
115138
});

0 commit comments

Comments
 (0)