Skip to content
This repository was archived by the owner on Feb 6, 2023. It is now read-only.

Commit c0e911c

Browse files
Frank Thompsonfacebook-github-bot
Frank Thompson
authored andcommitted
catch errors when encoding entity map
Summary: We've had several reports of people's content failing to save in the Performance tool. The only error message we have is this (with no callstack, unfortunately): ``` Unknown DraftEntity key: undefined. ``` I poked around in the DraftJS code, and my guess is that this is due to some character having an entity key associated with it that for whatever reason does not appear in the entity map. This diff "fixes" the issue by not throwing an error in this situation. This is definitely not as good as figuring out the root cause of the entity mismatch, but it seems reasonable for `convertFromDraftStateToRaw` to work with slightly malformed input. Not sure if it's ok to use `FBLogger` in this code or not, but I saw another usage of it in `draft-js-contrib` here: diffusion/WWW/browse/master/html/shared/draft-js-contrib/matchers/getImplicitDateTimeMatches.js;1000956292$34 I could also just ignore the error, but the linter didn't like that ¯\_(ツ)_/¯ Reviewed By: niveditc Differential Revision: D16362778 fbshipit-source-id: 6e2a6041d1a02b412d94655c9b6224fee868748d
1 parent db792ef commit c0e911c

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

src/model/encoding/__tests__/__snapshots__/convertFromDraftStateToRaw-test.js.snap

+23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`must be able to convert from draft state entities not in map 1`] = `
4+
Object {
5+
"blocks": Array [
6+
Object {
7+
"data": Object {},
8+
"depth": 0,
9+
"entityRanges": Array [
10+
Object {
11+
"key": 0,
12+
"length": 7,
13+
"offset": 0,
14+
},
15+
],
16+
"inlineStyleRanges": Array [],
17+
"key": "a",
18+
"text": "badlink",
19+
"type": "unstyled",
20+
},
21+
],
22+
"entityMap": Object {},
23+
}
24+
`;
25+
326
exports[`must be able to convert from draft state with ContentBlock to raw 1`] = `
427
Object {
528
"blocks": Array [

src/model/encoding/__tests__/convertFromDraftStateToRaw-test.js

+21-8
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ const treeContentState = contentState.set(
6161
]),
6262
);
6363

64-
const getMetadata = entityKey =>
65-
Immutable.Repeat(CharacterMetadata.create({entity: entityKey}), 5);
64+
const getMetadata = (entityKey, length) =>
65+
Immutable.Repeat(CharacterMetadata.create({entity: entityKey}), length);
6666
const getLink = entityKey =>
6767
new DraftEntityInstance({
6868
type: 'LINK',
@@ -79,23 +79,23 @@ const contentStateWithNonContiguousEntities = ContentState.createFromBlockArray(
7979
key: 'a',
8080
type: 'unstyled',
8181
text: 'link2 link2 link3',
82-
characterList: getMetadata('2')
82+
characterList: getMetadata('2', 5)
8383
.toList()
8484
.push(CharacterMetadata.EMPTY)
85-
.concat(getMetadata('2'))
85+
.concat(getMetadata('2', 5))
8686
.push(CharacterMetadata.EMPTY)
87-
.concat(getMetadata('3')),
87+
.concat(getMetadata('3', 5)),
8888
}),
8989
new ContentBlock({
9090
key: 'b',
9191
type: 'unstyled',
9292
text: 'link4 link2 link5',
93-
characterList: getMetadata('4')
93+
characterList: getMetadata('4', 5)
9494
.toList()
9595
.push(CharacterMetadata.EMPTY)
96-
.concat(getMetadata('2'))
96+
.concat(getMetadata('2', 5))
9797
.push(CharacterMetadata.EMPTY)
98-
.concat(getMetadata('5')),
98+
.concat(getMetadata('5', 5)),
9999
}),
100100
],
101101
)
@@ -104,6 +104,15 @@ const contentStateWithNonContiguousEntities = ContentState.createFromBlockArray(
104104
.addEntity(getLink('4'))
105105
.addEntity(getLink('5'));
106106

107+
const contentStateWithEntitiesNotInMap = ContentState.createFromBlockArray([
108+
new ContentBlock({
109+
key: 'a',
110+
type: 'unstyled',
111+
text: 'badlink',
112+
characterList: getMetadata('999', 7).toList(),
113+
}),
114+
]);
115+
107116
const assertConvertFromDraftStateToRaw = content => {
108117
expect(convertFromDraftStateToRaw(content)).toMatchSnapshot();
109118
};
@@ -119,3 +128,7 @@ test('must be able to convert from draft state with ContentBlockNode to raw', ()
119128
test('must be able to convert from draft state with noncontiguous entities to raw', () => {
120129
assertConvertFromDraftStateToRaw(contentStateWithNonContiguousEntities);
121130
});
131+
132+
test('must be able to convert from draft state entities not in map', () => {
133+
assertConvertFromDraftStateToRaw(contentStateWithEntitiesNotInMap);
134+
});

src/model/encoding/convertFromDraftStateToRaw.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type {RawDraftContentState} from 'RawDraftContentState';
1919
const ContentBlock = require('ContentBlock');
2020
const ContentBlockNode = require('ContentBlockNode');
2121
const DraftStringKey = require('DraftStringKey');
22+
const FBLogger = require('FBLogger');
2223

2324
const encodeEntityRanges = require('encodeEntityRanges');
2425
const encodeInlineStyleRanges = require('encodeInlineStyleRanges');
@@ -117,12 +118,16 @@ const encodeRawEntityMap = (
117118
const rawEntityMap = {};
118119

119120
Object.keys(entityMap).forEach((key, index) => {
120-
const entity = contentState.getEntity(DraftStringKey.unstringify(key));
121-
rawEntityMap[index] = {
122-
type: entity.getType(),
123-
mutability: entity.getMutability(),
124-
data: entity.getData(),
125-
};
121+
try {
122+
const entity = contentState.getEntity(DraftStringKey.unstringify(key));
123+
rawEntityMap[index] = {
124+
type: entity.getType(),
125+
mutability: entity.getMutability(),
126+
data: entity.getData(),
127+
};
128+
} catch (e) {
129+
FBLogger('draft-js-contrib').catching(e);
130+
}
126131
});
127132

128133
return {

0 commit comments

Comments
 (0)