Skip to content

Commit

Permalink
#1025: improve error handling around deploying running automations
Browse files Browse the repository at this point in the history
  • Loading branch information
JoernBerkefeld committed Jul 14, 2023
1 parent 1af9597 commit 5864211
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 22 deletions.
37 changes: 25 additions & 12 deletions docs/dist/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,7 @@ Automation MetadataType
* [.retrieveAsTemplate(templateDir, name, templateVariables)](#Automation.retrieveAsTemplate) ⇒ <code>Promise.&lt;TYPE.AutomationItemObj&gt;</code>
* [.postRetrieveTasks(metadata)](#Automation.postRetrieveTasks) ⇒ <code>TYPE.AutomationItem</code> \| <code>void</code>
* [.execute(keyArr)](#Automation.execute) ⇒ <code>Promise.&lt;boolean&gt;</code>
* [.getErrorsREST(ex)](#Automation.getErrorsREST) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
* [.pause(keyArr)](#Automation.pause) ⇒ <code>Promise.&lt;boolean&gt;</code>
* [.deploy(metadata, targetBU, retrieveDir)](#Automation.deploy) ⇒ <code>Promise.&lt;TYPE.AutomationMap&gt;</code>
* [.create(metadata)](#Automation.create) ⇒ <code>Promise</code>
Expand Down Expand Up @@ -1425,6 +1426,18 @@ a function to start query execution via API
| --- | --- | --- |
| keyArr | <code>Array.&lt;string&gt;</code> | customerkey of the metadata |

<a name="Automation.getErrorsREST"></a>

### Automation.getErrorsREST(ex) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
Standardizes a check for multiple messages but adds query specific filters to error texts

**Kind**: static method of [<code>Automation</code>](#Automation)
**Returns**: <code>Array.&lt;string&gt;</code> \| <code>void</code> - formatted Error Message

| Param | Type | Description |
| --- | --- | --- |
| ex | <code>object</code> | response payload from REST API |

<a name="Automation.pause"></a>

### Automation.pause(keyArr) ⇒ <code>Promise.&lt;boolean&gt;</code>
Expand Down Expand Up @@ -3332,7 +3345,7 @@ Provides default functionality that can be overwritten by child metadata type cl
* [.findSubType(templateDir, templateName)](#MetadataType.findSubType) ⇒ <code>Promise.&lt;string&gt;</code>
* [.readSecondaryFolder(templateDir, typeDirArr, templateName, fileName, ex)](#MetadataType.readSecondaryFolder) ⇒ <code>object</code>
* [.buildDefinition(templateDir, targetDir, templateName, variables)](#MetadataType.buildDefinition) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>
* [.checkForErrors(ex)](#MetadataType.checkForErrors) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
* [.getErrorsREST(ex)](#MetadataType.getErrorsREST) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
* [.document([metadata], [isDeploy])](#MetadataType.document) ⇒ <code>void</code>
* [.deleteByKey(customerKey)](#MetadataType.deleteByKey) ⇒ <code>boolean</code>
* [.postDeleteTasks(customerKey, [additionalExtensions])](#MetadataType.postDeleteTasks) ⇒ <code>Promise.&lt;void&gt;</code>
Expand Down Expand Up @@ -4053,9 +4066,9 @@ parsing is required (for example scripts & queries)
| templateName | <code>string</code> | name of the metadata file |
| variables | <code>TYPE.TemplateMap</code> | variables to be replaced in the metadata |

<a name="MetadataType.checkForErrors"></a>
<a name="MetadataType.getErrorsREST"></a>

### MetadataType.checkForErrors(ex) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
### MetadataType.getErrorsREST(ex) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
Standardizes a check for multiple messages

**Kind**: static method of [<code>MetadataType</code>](#MetadataType)
Expand Down Expand Up @@ -4741,7 +4754,7 @@ Query MetadataType
* [.buildDefinitionForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Query.buildDefinitionForNested) ⇒ <code>Promise.&lt;Array.&lt;Array.&lt;string&gt;&gt;&gt;</code>
* [.buildTemplateForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Query.buildTemplateForNested) ⇒ <code>Promise.&lt;Array.&lt;Array.&lt;string&gt;&gt;&gt;</code>
* [.getFilesToCommit(keyArr)](#Query.getFilesToCommit) ⇒ <code>Array.&lt;string&gt;</code>
* [.checkForErrors(ex)](#Query.checkForErrors) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
* [.getErrorsREST(ex)](#Query.getErrorsREST) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
* [.deleteByKey(customerKey)](#Query.deleteByKey) ⇒ <code>boolean</code>
* [.postDeleteTasks(customerKey)](#Query.postDeleteTasks) ⇒ <code>void</code>
* [.postDeployTasks(upsertResults)](#Query.postDeployTasks)
Expand Down Expand Up @@ -4908,9 +4921,9 @@ additionally, the documentation for dataExtension and automation should be retur
| --- | --- | --- |
| keyArr | <code>Array.&lt;string&gt;</code> | customerkey of the metadata |

<a name="Query.checkForErrors"></a>
<a name="Query.getErrorsREST"></a>

### Query.checkForErrors(ex) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
### Query.getErrorsREST(ex) ⇒ <code>Array.&lt;string&gt;</code> \| <code>void</code>
Standardizes a check for multiple messages but adds query specific filters to error texts

**Kind**: static method of [<code>Query</code>](#Query)
Expand Down Expand Up @@ -6402,9 +6415,9 @@ helper used by SOAP methods to ensure the type always uses an upper-cased first
**Kind**: static method of [<code>Util</code>](#Util)
**Returns**: <code>string</code> - str with first letter capitalized

| Param | Type |
| --- | --- |
| str | <code>string</code> |
| Param | Type | Description |
| --- | --- | --- |
| str | <code>string</code> | string to capitalize |

<a name="MetadataTypeDefinitions"></a>

Expand Down Expand Up @@ -8333,9 +8346,9 @@ helper used by SOAP methods to ensure the type always uses an upper-cased first
**Kind**: static method of [<code>Util</code>](#Util)
**Returns**: <code>string</code> - str with first letter capitalized

| Param | Type |
| --- | --- |
| str | <code>string</code> |
| Param | Type | Description |
| --- | --- | --- |
| str | <code>string</code> | string to capitalize |

<a name="csvToArray"></a>

Expand Down
31 changes: 30 additions & 1 deletion lib/metadataTypes/Automation.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ class Automation extends MetadataType {
key: m.CustomerKey,
name: m.Name,
programId: automationsLegacy.metadata[m.CustomerKey]?.id,
status: automationsLegacy.metadata[m.CustomerKey]?.status,
};
}
}
Expand Down Expand Up @@ -544,6 +545,25 @@ class Automation extends MetadataType {
static async #runOnce(metadataEntry) {
return super.executeSOAP(metadataEntry);
}

/**
* Standardizes a check for multiple messages but adds query specific filters to error texts
*
* @param {object} ex response payload from REST API
* @returns {string[] | void} formatted Error Message
*/
static getErrorsREST(ex) {
const errors = super.getErrorsREST(ex);
if (errors?.length > 0) {
return errors.map((msg) =>
msg
.split('403 Forbidden')
.join('403 Forbidden: Please check if the automation is currently running.')
);
}
return errors;
}

/**
* a function to start query execution via API
*
Expand Down Expand Up @@ -669,7 +689,16 @@ class Automation extends MetadataType {
* @returns {Promise} Promise
*/
static update(metadata, metadataBefore) {
metadata.id = metadataBefore.id;
if (metadataBefore.status === 'Running') {
Util.logger.error(
` ☇ error updating ${this.definition.type} ${
metadata[this.definition.keyField] || metadata[this.definition.nameField]
} / ${
metadata[this.definition.nameField]
}: You cannot update an automation that's currently running. Please wait a bit and retry.`
);
return null;
}
const uri = '/automation/v1/automations/' + metadata.id;
return super.updateREST(metadata, uri);
}
Expand Down
14 changes: 8 additions & 6 deletions lib/metadataTypes/MetadataType.js
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ class MetadataType {
);
return response;
} catch (ex) {
const parsedErrors = this.checkForErrors(ex);
const parsedErrors = this.getErrorsREST(ex);
Util.logger.error(
` ☇ error creating ${this.definition.type} ${
metadataEntry[this.definition.keyField] ||
Expand Down Expand Up @@ -884,7 +884,7 @@ class MetadataType {
// set to empty object in case API returned nothing to be able to update it in helper classes
const response = (await this.client.rest[httpMethod](uri, metadataEntry)) || {};
await this._postChangeKeyTasks(metadataEntry);
this.checkForErrors(response);
this.getErrorsREST(response);
await this.postUpdateTasks(metadataEntry, response);
// some times, e.g. automation dont return a key in their update response and hence we need to fall back to name
Util.logger.info(
Expand All @@ -895,7 +895,7 @@ class MetadataType {
);
return response;
} catch (ex) {
const parsedErrors = this.checkForErrors(ex);
const parsedErrors = this.getErrorsREST(ex);
Util.logger.error(
` ☇ error updating ${this.definition.type} ${
metadataEntry[this.definition.keyField] ||
Expand Down Expand Up @@ -1863,7 +1863,7 @@ class MetadataType {
* @param {object} ex response payload from REST API
* @returns {string[] | void} formatted Error Message
*/
static checkForErrors(ex) {
static getErrorsREST(ex) {
const errors = [];
if (ex?.response?.status >= 400 && ex?.response?.status < 600) {
if (ex.response.data.errors) {
Expand All @@ -1886,11 +1886,13 @@ class MetadataType {
}
} else if (ex.response.data.message) {
errors.push(ex.response.data.message);
} else {
} else if (ex.response.data) {
errors.push(`Undefined Errors: ${JSON.stringify(ex.response.data)}`);
Util.logger.debug(JSON.stringify(ex.response.data));
} else {
errors.push(`${ex.response.status} ${ex.response.statusText}`);
}
Util.logger.debug(JSON.stringify(ex.config));
Util.logger.debug(JSON.stringify(ex.response.data));
}
return errors;
}
Expand Down
5 changes: 3 additions & 2 deletions lib/metadataTypes/Query.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,12 @@ class Query extends MetadataType {
* @param {object} ex response payload from REST API
* @returns {string[] | void} formatted Error Message
*/
static checkForErrors(ex) {
const errors = super.checkForErrors(ex);
static getErrorsREST(ex) {
const errors = super.getErrorsREST(ex);
if (errors?.length > 0) {
return errors.map((msg) => msg.split('Error saving the Query field.').join(''));
}
return errors;
}
/**
* Delete a metadata item from the specified business unit
Expand Down
2 changes: 1 addition & 1 deletion lib/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ const Util = {
/**
* helper used by SOAP methods to ensure the type always uses an upper-cased first letter
*
* @param {string} str
* @param {string} str string to capitalize
* @returns {string} str with first letter capitalized
*/
capitalizeFirstLetter(str) {
Expand Down

0 comments on commit 5864211

Please sign in to comment.