Skip to content

Commit

Permalink
#2035: ensure assets with missing referenced content blocks get skipp…
Browse files Browse the repository at this point in the history
…ed during deployment
  • Loading branch information
JoernBerkefeld committed Feb 5, 2025
1 parent a422fa9 commit 54fe301
Show file tree
Hide file tree
Showing 17 changed files with 443 additions and 21 deletions.
4 changes: 2 additions & 2 deletions @types/lib/metadataTypes/Asset.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion @types/lib/metadataTypes/Asset.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion @types/lib/util/replaceContentBlockReference.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion @types/lib/util/replaceContentBlockReference.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 15 additions & 13 deletions lib/metadataTypes/Asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,13 @@ class Asset extends MetadataType {
}

/**
* Returns Order in which metadata needs to be retrieved/deployed
* Returns Order in which metadata needs to be retrieved/deployed and skips components with missing components
*
* @param {AssetMap} metadataMap metadata mapped by their keyField
* @param {string} deployDir directory where deploy metadata are saved
* @returns {Promise.<AssetMap>} keyField => metadata map but sorted to ensure dependencies are deployed in correct order
*/
static async _getUpsertOrder(metadataMap, deployDir) {
static async _getUpsertOrderAndSkipMissing(metadataMap, deployDir) {
/**
* one entry for each dependency with the first item being the key thats required by the second item
*
Expand Down Expand Up @@ -225,11 +225,14 @@ class Asset extends MetadataType {
dependencies.push([undefined, key]);
}
} catch (ex) {
if (ex.code !== 200) {
Util.logger.errorStack(ex, 'Cannot find related code blocks for ' + key);
if (ex.code === 200) {
// no dependent keys found
dependencies.push([undefined, key]);
} else {
Util.logger.error(
` ☇ skipping ${this.definition.type} ${key}: content block ${ex.message} that is referenced via ContentBlockByX was not found on BU nor in deployment package`
);
}
// no dependent keys found
dependencies.push([undefined, key]);
}
}

Expand All @@ -255,13 +258,12 @@ class Asset extends MetadataType {
* @returns {Promise.<AssetMap>} keyField => metadata map
*/
static async upsert(metadataMap, deployDir) {
if (Object.keys(metadataMap).length > 1) {
// fill the cache map with our deployment package to ensure we can find
ReplaceCbReference.createCacheForMap(cache.getCache().asset);
ReplaceCbReference.createCacheForMap(metadataMap);
// assets can link to other assets (via template, content block reference and SSJS/AMPscript) and deployment would fail if we did not sort this here
metadataMap = await this._getUpsertOrder(metadataMap, deployDir);
}
// fill the cache map with our deployment package to ensure we can find
ReplaceCbReference.createCacheForMap(cache.getCache().asset);
// await ReplaceCbReference.createCache(this.properties, this.buObject, true);
ReplaceCbReference.createCacheForMap(metadataMap);
// assets can link to other assets (via template, content block reference and SSJS/AMPscript) and deployment would fail if we did not sort this here
metadataMap = await this._getUpsertOrderAndSkipMissing(metadataMap, deployDir);
return super.upsert(metadataMap, deployDir, true);
}

Expand Down
13 changes: 10 additions & 3 deletions lib/util/replaceContentBlockReference.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ export default class ReplaceContentBlockReference {
from,
identifier,
parentName,
lang.isSsjs
lang.isSsjs,
!!findAssetKeys
);
if (referencedAsset && referencedAsset[to]) {
// make sure we not only found the asset but also have a replacement for it (folder issue could block swap to ContentBlockByName)
Expand All @@ -145,6 +146,11 @@ export default class ReplaceContentBlockReference {
Util.logger.error(
` - ${parentName}: Asset ${from} ${identifier} has no valid ${to} reference`
);
} else if (!referencedAsset && findAssetKeys) {
const newError = new Error(`${identifier}`);
// @ts-expect-error custom error object
newError.code = 404;
throw newError;
}
return match;
}
Expand All @@ -167,9 +173,10 @@ export default class ReplaceContentBlockReference {
* @param {string|number} identifier id, key or name of asset
* @param {string} parentName name of the object that was passed in; used in error message only
* @param {boolean} [isSsjs] replaces backslashes with double backslashes in name if true
* @param {boolean} [handleOutside] don not print error message if asset not found
* @returns {AssetItemSimple} asset object
*/
static #getAssetBy(from, identifier, parentName, isSsjs = false) {
static #getAssetBy(from, identifier, parentName, isSsjs = false, handleOutside = false) {
let reference;
switch (from) {
case 'id': {
Expand All @@ -188,7 +195,7 @@ export default class ReplaceContentBlockReference {
break;
}
}
if (!reference) {
if (!reference && !handleOutside) {
Util.logger.error(` - ${parentName}: Asset not found for ${from} ${identifier}`);
}
return reference;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<html></html>
Loading

0 comments on commit 54fe301

Please sign in to comment.