Skip to content

Commit cebb49f

Browse files
authored
fix: improve cache handling and error recovery (docsifyjs#2744)
1 parent 7900bea commit cebb49f

4 files changed

Lines changed: 65 additions & 7 deletions

File tree

src/core/render/embed.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ function walkFetchEmbed({ embedTokens, compile, fetch }, cb) {
122122
};
123123

124124
if (currentToken.embed.url) {
125-
get(currentToken.embed.url).then(next);
125+
get(currentToken.embed.url).then(next, () => next());
126126
} else {
127127
next(currentToken.embed.html);
128128
}
@@ -205,7 +205,7 @@ export function prerenderEmbed({ compiler, raw = '', fetch }, done) {
205205
walkFetchEmbed(
206206
{ compile, embedTokens, fetch },
207207
({ embedToken, token, rowIndex, cellIndex, tokenRef }) => {
208-
if (token) {
208+
if (token && embedToken) {
209209
Object.assign(links, embedToken.links);
210210

211211
if (typeof rowIndex === 'number' && typeof cellIndex === 'number') {
@@ -269,7 +269,7 @@ export function prerenderEmbed({ compiler, raw = '', fetch }, done) {
269269
});
270270
}
271271
}
272-
} else {
272+
} else if (!token) {
273273
cached[raw] = tokens.concat();
274274
tokens.links = cached[raw].links = links;
275275
done(tokens);

src/core/util/core.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ export function cached(fn) {
1010
const cache = Object.create(null);
1111
return function (str) {
1212
const key = isPrimitive(str) ? str : JSON.stringify(str);
13-
const hit = cache[key];
14-
return hit || (cache[key] = fn(str));
13+
if (key in cache) {
14+
return cache[key];
15+
}
16+
17+
return (cache[key] = fn(str));
1518
};
1619
}
1720

test/integration/embed.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,35 @@ Command | Description | Parameters
262262
expect(mainText).not.toContain("_media/second.md ':include'");
263263
});
264264

265+
test('failed embed URL does not block page render', async () => {
266+
await docsifyInit({
267+
markdown: {
268+
homepage: `
269+
# Embed Test
270+
271+
[missing](_media/missing.md ':include')
272+
273+
Text after missing embed
274+
275+
[ok](_media/ok.md ':include')
276+
`,
277+
},
278+
routes: {
279+
'_media/missing.md': {
280+
status: 404,
281+
body: 'Not Found',
282+
contentType: 'text/markdown',
283+
},
284+
'_media/ok.md': 'reachable include content',
285+
},
286+
});
287+
288+
expect(await waitForText('#main', 'Text after missing embed')).toBeTruthy();
289+
expect(
290+
await waitForText('#main', 'reachable include content'),
291+
).toBeTruthy();
292+
});
293+
265294
test('embed file table cell', async () => {
266295
await docsifyInit({
267296
markdown: {

test/unit/core-util.test.js

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,38 @@
1-
import { isExternal } from '../../src/core/util/index.js';
1+
import { cached, isExternal } from '../../src/core/util/index.js';
22

33
// Core util
44
// -----------------------------------------------------------------------------
55
describe('core/util', () => {
6+
describe('cached()', () => {
7+
test('memoizes falsy return values', () => {
8+
let calls = 0;
9+
const fn = cached(() => {
10+
calls += 1;
11+
return '';
12+
});
13+
14+
expect(fn('same-key')).toBe('');
15+
expect(fn('same-key')).toBe('');
16+
expect(calls).toBe(1);
17+
});
18+
19+
test('memoizes undefined return values', () => {
20+
let calls = 0;
21+
const fn = cached(() => {
22+
calls += 1;
23+
return undefined;
24+
});
25+
26+
expect(fn('same-key')).toBeUndefined();
27+
expect(fn('same-key')).toBeUndefined();
28+
expect(calls).toBe(1);
29+
});
30+
});
31+
632
// isExternal()
733
// ---------------------------------------------------------------------------
834
describe('isExternal()', () => {
9-
// cases non external
35+
// cases non-external
1036
test('non external local url with one /', () => {
1137
const result = isExternal(`/${location.host}/docsify/demo.md`);
1238

0 commit comments

Comments
 (0)