Skip to content

Commit 5b06788

Browse files
kmanijakkmanijakgziolo
authored
Fail gracefully when block in createBlock function is not registered (#68043)
* Make __experimentalSanitizeBlockAttributes fail gracefully when block is not registered * Check if block is registered before sanitizing attributes * Update tests and add new ones * Bring back the error throwing * Simplify the test * Refactor block creation functions for improved readability/ In both cases they rely on internal handling of `createBlock` function. Co-authored-by: kmanijak <karolmanijak@git.wordpress.org> Co-authored-by: gziolo <gziolo@git.wordpress.org>
1 parent 7534ae9 commit 5b06788

File tree

4 files changed

+58
-36
lines changed

4 files changed

+58
-36
lines changed

packages/blocks/src/api/factory.js

+31-24
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
getGroupingBlockName,
1818
} from './registration';
1919
import {
20+
isBlockRegistered,
2021
normalizeBlockType,
2122
__experimentalSanitizeBlockAttributes,
2223
} from './utils';
@@ -31,6 +32,14 @@ import {
3132
* @return {Object} Block object.
3233
*/
3334
export function createBlock( name, attributes = {}, innerBlocks = [] ) {
35+
if ( ! isBlockRegistered( name ) ) {
36+
return createBlock( 'core/missing', {
37+
originalName: name,
38+
originalContent: '',
39+
originalUndelimitedContent: '',
40+
} );
41+
}
42+
3443
const sanitizedAttributes = __experimentalSanitizeBlockAttributes(
3544
name,
3645
attributes
@@ -94,15 +103,22 @@ export function __experimentalCloneSanitizedBlock(
94103
mergeAttributes = {},
95104
newInnerBlocks
96105
) {
106+
const { name } = block;
107+
108+
if ( ! isBlockRegistered( name ) ) {
109+
return createBlock( 'core/missing', {
110+
originalName: name,
111+
originalContent: '',
112+
originalUndelimitedContent: '',
113+
} );
114+
}
115+
97116
const clientId = uuid();
98117

99-
const sanitizedAttributes = __experimentalSanitizeBlockAttributes(
100-
block.name,
101-
{
102-
...block.attributes,
103-
...mergeAttributes,
104-
}
105-
);
118+
const sanitizedAttributes = __experimentalSanitizeBlockAttributes( name, {
119+
...block.attributes,
120+
...mergeAttributes,
121+
} );
106122

107123
return {
108124
...block,
@@ -583,20 +599,11 @@ export function switchToBlockType( blocks, name ) {
583599
*
584600
* @return {Object} block.
585601
*/
586-
export const getBlockFromExample = ( name, example ) => {
587-
try {
588-
return createBlock(
589-
name,
590-
example.attributes,
591-
( example.innerBlocks ?? [] ).map( ( innerBlock ) =>
592-
getBlockFromExample( innerBlock.name, innerBlock )
593-
)
594-
);
595-
} catch {
596-
return createBlock( 'core/missing', {
597-
originalName: name,
598-
originalContent: '',
599-
originalUndelimitedContent: '',
600-
} );
601-
}
602-
};
602+
export const getBlockFromExample = ( name, example ) =>
603+
createBlock(
604+
name,
605+
example.attributes,
606+
( example.innerBlocks ?? [] ).map( ( innerBlock ) =>
607+
getBlockFromExample( innerBlock.name, innerBlock )
608+
)
609+
);

packages/blocks/src/api/templates.js

+1-12
Original file line numberDiff line numberDiff line change
@@ -109,23 +109,12 @@ export function synchronizeBlocksWithTemplate( blocks = [], template ) {
109109
attributes
110110
);
111111

112-
let [ blockName, blockAttributes ] =
112+
const [ blockName, blockAttributes ] =
113113
convertLegacyBlockNameAndAttributes(
114114
name,
115115
normalizedAttributes
116116
);
117117

118-
// If a Block is undefined at this point, use the core/missing block as
119-
// a placeholder for a better user experience.
120-
if ( undefined === getBlockType( blockName ) ) {
121-
blockAttributes = {
122-
originalName: name,
123-
originalContent: '',
124-
originalUndelimitedContent: '',
125-
};
126-
blockName = 'core/missing';
127-
}
128-
129118
return createBlock(
130119
blockName,
131120
blockAttributes,

packages/blocks/src/api/test/utils.js

+15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
isUnmodifiedDefaultBlock,
1313
getAccessibleBlockLabel,
1414
getBlockLabel,
15+
isBlockRegistered,
1516
__experimentalSanitizeBlockAttributes,
1617
getBlockAttributesNamesByRole,
1718
isContentBlock,
@@ -213,6 +214,20 @@ describe( 'getAccessibleBlockLabel', () => {
213214
} );
214215
} );
215216

217+
describe( 'isBlockRegistered', () => {
218+
it( 'returns true if the block is registered', () => {
219+
registerBlockType( 'core/test-block', { title: 'Test block' } );
220+
expect( isBlockRegistered( 'core/test-block' ) ).toBe( true );
221+
unregisterBlockType( 'core/test-block' );
222+
} );
223+
224+
it( 'returns false if the block is not registered', () => {
225+
expect( isBlockRegistered( 'core/not-registered-test-block' ) ).toBe(
226+
false
227+
);
228+
} );
229+
} );
230+
216231
describe( 'sanitizeBlockAttributes', () => {
217232
afterEach( () => {
218233
getBlockTypes().forEach( ( block ) => {

packages/blocks/src/api/utils.js

+11
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,17 @@ export function getDefault( attributeSchema ) {
266266
}
267267
}
268268

269+
/**
270+
* Check if a block is registered.
271+
*
272+
* @param {string} name The block's name.
273+
*
274+
* @return {boolean} Whether the block is registered.
275+
*/
276+
export function isBlockRegistered( name ) {
277+
return getBlockType( name ) !== undefined;
278+
}
279+
269280
/**
270281
* Ensure attributes contains only values defined by block type, and merge
271282
* default values for missing attributes.

0 commit comments

Comments
 (0)