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

Commit

Permalink
catch errors when encoding entity map
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Frank Thompson authored and facebook-github-bot committed Jul 19, 2019
1 parent db792ef commit c0e911c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`must be able to convert from draft state entities not in map 1`] = `
Object {
"blocks": Array [
Object {
"data": Object {},
"depth": 0,
"entityRanges": Array [
Object {
"key": 0,
"length": 7,
"offset": 0,
},
],
"inlineStyleRanges": Array [],
"key": "a",
"text": "badlink",
"type": "unstyled",
},
],
"entityMap": Object {},
}
`;

exports[`must be able to convert from draft state with ContentBlock to raw 1`] = `
Object {
"blocks": Array [
Expand Down
29 changes: 21 additions & 8 deletions src/model/encoding/__tests__/convertFromDraftStateToRaw-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ const treeContentState = contentState.set(
]),
);

const getMetadata = entityKey =>
Immutable.Repeat(CharacterMetadata.create({entity: entityKey}), 5);
const getMetadata = (entityKey, length) =>
Immutable.Repeat(CharacterMetadata.create({entity: entityKey}), length);
const getLink = entityKey =>
new DraftEntityInstance({
type: 'LINK',
Expand All @@ -79,23 +79,23 @@ const contentStateWithNonContiguousEntities = ContentState.createFromBlockArray(
key: 'a',
type: 'unstyled',
text: 'link2 link2 link3',
characterList: getMetadata('2')
characterList: getMetadata('2', 5)
.toList()
.push(CharacterMetadata.EMPTY)
.concat(getMetadata('2'))
.concat(getMetadata('2', 5))
.push(CharacterMetadata.EMPTY)
.concat(getMetadata('3')),
.concat(getMetadata('3', 5)),
}),
new ContentBlock({
key: 'b',
type: 'unstyled',
text: 'link4 link2 link5',
characterList: getMetadata('4')
characterList: getMetadata('4', 5)
.toList()
.push(CharacterMetadata.EMPTY)
.concat(getMetadata('2'))
.concat(getMetadata('2', 5))
.push(CharacterMetadata.EMPTY)
.concat(getMetadata('5')),
.concat(getMetadata('5', 5)),
}),
],
)
Expand All @@ -104,6 +104,15 @@ const contentStateWithNonContiguousEntities = ContentState.createFromBlockArray(
.addEntity(getLink('4'))
.addEntity(getLink('5'));

const contentStateWithEntitiesNotInMap = ContentState.createFromBlockArray([
new ContentBlock({
key: 'a',
type: 'unstyled',
text: 'badlink',
characterList: getMetadata('999', 7).toList(),
}),
]);

const assertConvertFromDraftStateToRaw = content => {
expect(convertFromDraftStateToRaw(content)).toMatchSnapshot();
};
Expand All @@ -119,3 +128,7 @@ test('must be able to convert from draft state with ContentBlockNode to raw', ()
test('must be able to convert from draft state with noncontiguous entities to raw', () => {
assertConvertFromDraftStateToRaw(contentStateWithNonContiguousEntities);
});

test('must be able to convert from draft state entities not in map', () => {
assertConvertFromDraftStateToRaw(contentStateWithEntitiesNotInMap);
});
17 changes: 11 additions & 6 deletions src/model/encoding/convertFromDraftStateToRaw.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {RawDraftContentState} from 'RawDraftContentState';
const ContentBlock = require('ContentBlock');
const ContentBlockNode = require('ContentBlockNode');
const DraftStringKey = require('DraftStringKey');
const FBLogger = require('FBLogger');

const encodeEntityRanges = require('encodeEntityRanges');
const encodeInlineStyleRanges = require('encodeInlineStyleRanges');
Expand Down Expand Up @@ -117,12 +118,16 @@ const encodeRawEntityMap = (
const rawEntityMap = {};

Object.keys(entityMap).forEach((key, index) => {
const entity = contentState.getEntity(DraftStringKey.unstringify(key));
rawEntityMap[index] = {
type: entity.getType(),
mutability: entity.getMutability(),
data: entity.getData(),
};
try {
const entity = contentState.getEntity(DraftStringKey.unstringify(key));
rawEntityMap[index] = {
type: entity.getType(),
mutability: entity.getMutability(),
data: entity.getData(),
};
} catch (e) {
FBLogger('draft-js-contrib').catching(e);
}
});

return {
Expand Down

0 comments on commit c0e911c

Please sign in to comment.