Skip to content

Commit 28d28e6

Browse files
Improved error handling (#4)
* Added improved error handling. All errors from the plugin (including validation errors) are caught now and returned as status: error * Improved try catch block. Added isDebug check to return error stack instead of just the message. Fixed tests * Fixed transform value bug * Bug fixes for create plan not using the transformed desired parameters * Modified parameter to canModify
1 parent 44743dd commit 28d28e6

13 files changed

Lines changed: 218 additions & 72 deletions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codify-plugin-lib",
3-
"version": "1.0.55",
3+
"version": "1.0.57",
44
"description": "",
55
"main": "dist/index.js",
66
"typings": "dist/index.d.ts",

src/entities/plan-types.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import { ResourceOperation } from 'codify-schemas';
2-
31
/**
42
* Customize properties for specific parameters. This will alter the way the library process changes to the parameter.
53
*/
64
export interface ParameterOptions {
75
/**
8-
* Chose if the resource should be re-created or modified if this parameter is changed. Defaults to re-create.
6+
* Chose if the resource should be re-created or modified if this parameter is changed. Defaults to false (re-creates resource on change).
97
*/
10-
planOperation?: ResourceOperation.MODIFY | ResourceOperation.RECREATE;
8+
canModify?: boolean;
119
/**
1210
* Customize the equality comparison for a parameter.
1311
* @param a

src/entities/plan.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ export class Plan<T extends StringIndexedObject> {
5555
let newOperation: ResourceOperation;
5656
if (statefulParameterNames.has(curr.name)) {
5757
newOperation = ResourceOperation.MODIFY // All stateful parameters are modify only
58-
} else if (parameterOptions[curr.name]?.planOperation) {
59-
newOperation = parameterOptions[curr.name].planOperation!;
58+
} else if (parameterOptions[curr.name]?.canModify) {
59+
newOperation = parameterOptions[curr.name].canModify ? ResourceOperation.MODIFY : ResourceOperation.RECREATE;
6060
} else {
6161
newOperation = ResourceOperation.RECREATE; // Default to Re-create. Should handle the majority of use cases
6262
}

src/entities/plugin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export class Plugin {
1515
planStorage: Map<string, Plan<ResourceConfig>>;
1616

1717
constructor(
18+
public name: string,
1819
public resources: Map<string, Resource<ResourceConfig>>
1920
) {
2021
this.planStorage = new Map();

src/entities/resource-parameters.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ describe('Resource parameter tests', () => {
8080
type: 'resource',
8181
parameterOptions: {
8282
propA: { statefulParameter: statefulParameterSpy },
83-
propB: { planOperation: ResourceOperation.MODIFY },
83+
propB: { canModify: true },
8484
}
8585
});
8686
}

src/entities/resource-types.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
import { ResourceOperation } from 'codify-schemas';
2-
31
export type ErrorMessage = string;
42

53
/**
64
* Customize properties for specific parameters. This will alter the way the library process changes to the parameter.
75
*/
86
export interface ResourceParameterOptions {
97
/**
10-
* Chose if the resource should be re-created or modified if this parameter is changed. Defaults to re-create.
8+
* Chose if the resource should be re-created or modified if this parameter is changed. Defaults to false (re-create).
119
*/
12-
planOperation?: ResourceOperation.MODIFY | ResourceOperation.RECREATE;
10+
canModify?: boolean;
1311
/**
1412
* Customize the equality comparison for a parameter.
1513
* @param desired
@@ -19,7 +17,7 @@ export interface ResourceParameterOptions {
1917
/**
2018
* Default value for the parameter. If a value is not provided in the config, the library will use this value.
2119
*/
22-
default?: unknown,
20+
default?: unknown;
2321
}
2422

2523
/**

src/entities/resource.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ describe('Resource tests', () => {
195195
super({
196196
type: 'resource',
197197
parameterOptions: {
198-
propA: { planOperation: ResourceOperation.MODIFY },
199-
propB: { planOperation: ResourceOperation.MODIFY },
198+
propA: { canModify: true },
199+
propB: { canModify: true },
200200
}
201201
});
202202
}
@@ -244,7 +244,7 @@ describe('Resource tests', () => {
244244
type: 'type',
245245
dependencies: ['homebrew', 'python'],
246246
parameterOptions: {
247-
propA: { planOperation: ResourceOperation.MODIFY },
247+
propA: { canModify: true },
248248
propB: { statefulParameter },
249249
propC: { isEqual: (a, b) => true },
250250
}
@@ -281,7 +281,7 @@ describe('Resource tests', () => {
281281
type: 'type',
282282
dependencies: ['homebrew', 'python'],
283283
parameterOptions: {
284-
propA: { planOperation: ResourceOperation.MODIFY },
284+
propA: { canModify: true },
285285
propB: { statefulParameter },
286286
propC: { isEqual: (a, b) => true },
287287
}

src/entities/resource.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export abstract class Resource<T extends StringIndexedObject> {
101101

102102
// Short circuit here. If the resource is non-existent, there's no point checking stateful parameters
103103
if (currentParameters == null) {
104-
return Plan.create(desiredParameters, null, resourceMetadata, planOptions);
104+
return Plan.create(resourceParameters, null, resourceMetadata, planOptions);
105105
}
106106

107107
// Refresh stateful parameters. These parameters have state external to the resource
@@ -161,7 +161,7 @@ export abstract class Resource<T extends StringIndexedObject> {
161161

162162
for (const pc of statelessParameterChanges) {
163163
// TODO: When stateful mode is added in the future. Dynamically choose if deletes are allowed
164-
await this.applyModify(pc.name, pc.newValue, pc.previousValue, false, plan);
164+
await this.applyModify(pc, plan);
165165
}
166166

167167
const statefulParameterChanges = parameterChanges
@@ -228,21 +228,17 @@ Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`
228228
const orderedEntries = [...Object.entries(transformParameters)]
229229
.sort(([keyA], [keyB]) => this.transformParameterOrder.get(keyA)! - this.transformParameterOrder.get(keyB)!)
230230

231-
for (const [key] of orderedEntries) {
232-
if (desired[key] !== null) {
233-
const transformedValue = await this.transformParameters.get(key)!.transform(desired[key]);
231+
for (const [key, value] of orderedEntries) {
232+
const transformedValue = await this.transformParameters.get(key)!.transform(value);
234233

235-
if (Object.keys(transformedValue).some((k) => desired[k] !== undefined)) {
236-
throw new Error(`Transform parameter ${key as string} is attempting to override existing value ${desired[key]}`);
237-
}
238-
239-
Object.entries(transformedValue).forEach(([tvKey, tvValue]) => {
240-
// @ts-ignore
241-
desired[tvKey] = tvValue;
242-
})
243-
244-
delete desired[key];
234+
if (Object.keys(transformedValue).some((k) => desired[k] !== undefined)) {
235+
throw new Error(`Transform parameter ${key as string} is attempting to override existing values ${JSON.stringify(transformedValue, null, 2)}`);
245236
}
237+
238+
Object.entries(transformedValue).forEach(([tvKey, tvValue]) => {
239+
// @ts-ignore
240+
desired[tvKey] = tvValue;
241+
})
246242
}
247243
}
248244

@@ -314,7 +310,7 @@ Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`
314310

315311
abstract applyCreate(plan: Plan<T>): Promise<void>;
316312

317-
async applyModify(parameterName: keyof T, newValue: unknown, previousValue: unknown, allowDeletes: boolean, plan: Plan<T>): Promise<void> {};
313+
async applyModify(pc: ParameterChange<T>, plan: Plan<T>): Promise<void> {};
318314

319315
abstract applyDestroy(plan: Plan<T>): Promise<void>;
320316
}

src/entities/transform-parameter.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { StringIndexedObject } from 'codify-schemas';
22

3+
/**
4+
* Transform parameters convert the provided value into
5+
* other parameters. Transform parameters will not show up
6+
* in the refresh or the plan. Transform parameters get processed after
7+
* default values.
8+
*/
39
export abstract class TransformParameter<T extends StringIndexedObject> {
410

511
abstract transform(value: any): Promise<Partial<T>>

src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,3 @@ export async function runPlugin(plugin: Plugin) {
1616
const messageHandler = new MessageHandler(plugin);
1717
process.on('message', (message) => messageHandler.onMessage(message))
1818
}
19-
export { ErrorMessage } from './entities/resource-types.js';

0 commit comments

Comments
 (0)