Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): make IResolvable.creationStack required #2912

Merged
merged 1 commit into from
Jun 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/@aws-cdk/aws-events/lib/input.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DefaultTokenResolver, IResolvable, IResolveContext,
Lazy, Stack, StringConcat, Token, Tokenization } from '@aws-cdk/cdk';
import { captureStackTrace, DefaultTokenResolver, IResolvable,
IResolveContext, Lazy, Stack, StringConcat, Token, Tokenization } from '@aws-cdk/cdk';
import { IRule } from './rule-ref';

/**
Expand Down Expand Up @@ -274,10 +274,12 @@ export class EventField implements IResolvable {
}

public readonly displayHint: string;
public readonly creationStack: string[];

private constructor(public readonly path: string) {
this.displayHint = this.path.replace(/^[^a-zA-Z0-9_-]+/, '').replace(/[^a-zA-Z0-9_-]/g, '-');
Object.defineProperty(this, EVENT_FIELD_SYMBOL, { value: true });
this.creationStack = captureStackTrace();
}

public resolve(_ctx: IResolveContext): any {
Expand Down
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-iam/lib/policy-document.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import cdk = require('@aws-cdk/cdk');
import { IPostProcessor } from '@aws-cdk/cdk';
import { captureStackTrace, IPostProcessor } from '@aws-cdk/cdk';
import { PolicyStatement } from './policy-statement';

/**
Expand All @@ -25,10 +25,12 @@ export interface PolicyDocumentProps {
* A PolicyDocument is a collection of statements
*/
export class PolicyDocument implements cdk.IResolvable {
public readonly creationStack: string[];
private readonly statements = new Array<PolicyStatement>();
private readonly autoAssignSids: boolean;

constructor(props: PolicyDocumentProps = {}) {
this.creationStack = captureStackTrace();
this.autoAssignSids = !!props.assignSids;

this.addStatements(...props.statements || []);
Expand Down
6 changes: 5 additions & 1 deletion packages/@aws-cdk/aws-iam/lib/principals.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import cdk = require('@aws-cdk/cdk');
import { Stack } from '@aws-cdk/cdk';
import { captureStackTrace, Stack } from '@aws-cdk/cdk';
import { Default, RegionInfo } from '@aws-cdk/region-info';
import { PolicyStatement } from './policy-statement';
import { mergePrincipal } from './util';
Expand Down Expand Up @@ -312,7 +312,9 @@ export class CompositePrincipal extends PrincipalBase {
* A lazy token that requires an instance of Stack to evaluate
*/
class StackDependentToken implements cdk.IResolvable {
public readonly creationStack: string[];
constructor(private readonly fn: (stack: cdk.Stack) => any) {
this.creationStack = captureStackTrace();
}

public resolve(context: cdk.IResolveContext) {
Expand All @@ -329,8 +331,10 @@ class StackDependentToken implements cdk.IResolvable {
}

class ServicePrincipalToken implements cdk.IResolvable {
public readonly creationStack: string[];
constructor(private readonly service: string,
private readonly opts: ServicePrincipalOpts) {
this.creationStack = captureStackTrace();
}

public resolve(ctx: cdk.IResolveContext) {
Expand Down
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-stepfunctions/lib/json-path.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IResolvable, IResolveContext, Token, Tokenization } from '@aws-cdk/cdk';
import { captureStackTrace, IResolvable, IResolveContext, Token, Tokenization } from '@aws-cdk/cdk';

const JSON_PATH_TOKEN_SYMBOL = Symbol.for('@aws-cdk/aws-stepfunctions.JsonPathToken');

Expand All @@ -7,9 +7,11 @@ export class JsonPathToken implements IResolvable {
return (x as any)[JSON_PATH_TOKEN_SYMBOL] === true;
}

public readonly creationStack: string[];
public displayHint: string;

constructor(public readonly path: string) {
this.creationStack = captureStackTrace();
this.displayHint = path.replace(/^[^a-zA-Z]+/, '');
Object.defineProperty(this, JSON_PATH_TOKEN_SYMBOL, { value: true });
}
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/cdk/lib/cfn-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export abstract class CfnElement extends Construct {
* from the +metadata+ entry typed +aws:cdk:logicalId+, and with the bottom-most
* node +internal+ entries filtered.
*/
public get creationStackTrace(): string[] | undefined {
public get creationStack(): string[] | undefined {
const trace = this.node.metadata.find(md => md.type === cxapi.LOGICAL_ID_METADATA_KEY)!.trace;
if (!trace) {
return undefined;
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/cdk/lib/cfn-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export class CfnResource extends CfnRefElement {
// Change message
e.message = `While synthesizing ${this.node.path}: ${e.message}`;
// Adjust stack trace (make it look like node built it, too...)
const trace = this.creationStackTrace;
const trace = this.creationStack;
if (trace) {
const creationStack = ['--- resource created at ---', ...trace].join('\n at ');
const problemTrace = e.stack.substr(e.stack.indexOf(e.message) + e.message.length);
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/cdk/lib/construct.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import cxapi = require('@aws-cdk/cx-api');
import { IAspect } from './aspect';
import { DependableTrait, IDependable } from './dependency';
import { createStackTrace } from './private/stack-trace';
import { IResolvable } from './resolvable';
import { captureStackTrace } from './stack-trace';
import { Token } from './token';
import { makeUniqueId } from './uniqueid';

Expand Down Expand Up @@ -312,7 +312,7 @@ export class ConstructNode {
return;
}

const trace = this.tryGetContext(cxapi.DISABLE_METADATA_STACK_TRACE) ? undefined : createStackTrace(from || this.addMetadata);
const trace = this.tryGetContext(cxapi.DISABLE_METADATA_STACK_TRACE) ? undefined : captureStackTrace(from || this.addMetadata);
this._metadata.push({ type, data, trace });
}

Expand Down
4 changes: 4 additions & 0 deletions packages/@aws-cdk/cdk/lib/fn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ICfnConditionExpression } from './cfn-condition';
import { minimalCloudFormationJoin } from './cloudformation-lang';
import { Intrinsic } from './private/intrinsic';
import { IResolvable, IResolveContext } from './resolvable';
import { captureStackTrace } from './stack-trace';
import { Token } from './token';

// tslint:disable:max-line-length
Expand Down Expand Up @@ -630,6 +631,8 @@ class FnValueOfAll extends FnBase {
* with no delimiter.
*/
class FnJoin implements IResolvable {
public readonly creationStack: string[];

private readonly delimiter: string;
private readonly listOfValues: any[];
// Cache for the result of resolveValues() - since it otherwise would be computed several times
Expand All @@ -648,6 +651,7 @@ class FnJoin implements IResolvable {

this.delimiter = delimiter;
this.listOfValues = listOfValues;
this.creationStack = captureStackTrace();
}

public resolve(context: IResolveContext): any {
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/cdk/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export * from './cfn-dynamic-reference';
export * from './tag';
export * from './removal-policy';
export * from './arn';
export * from './stack-trace';

export * from './app';
export * from './context';
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/cdk/lib/lazy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createStackTrace } from './private/stack-trace';
import { IResolvable, IResolveContext } from "./resolvable";
import { captureStackTrace } from './stack-trace';
import { Token } from "./token";

/**
Expand Down Expand Up @@ -123,7 +123,7 @@ abstract class LazyBase implements IResolvable {
public readonly creationStack: string[];

constructor() {
this.creationStack = createStackTrace();
this.creationStack = captureStackTrace();
}

public abstract resolve(context: IResolveContext): any;
Expand Down
4 changes: 4 additions & 0 deletions packages/@aws-cdk/cdk/lib/private/cross-environment-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ArnComponents } from '../arn';
import { IResolvable, IResolveContext } from '../resolvable';
import { IResource } from '../resource';
import { Stack } from '../stack';
import { captureStackTrace } from '../stack-trace';

/**
* A Token that represents a reference that spans accounts and/or regions,
Expand All @@ -11,6 +12,8 @@ import { Stack } from '../stack';
* This class is private to the @aws-cdk/cdk package.
*/
export abstract class CrossEnvironmentToken implements IResolvable {
public readonly creationStack: string[];

/**
* @param regularValue the value used when this is referenced NOT from a cross account and/or region Stack
* @param crossEnvironmentValue the value used when this is referenced from a cross account and/or region Stack
Expand All @@ -20,6 +23,7 @@ export abstract class CrossEnvironmentToken implements IResolvable {
protected constructor(private readonly regularValue: string, private readonly crossEnvironmentValue: any,
private readonly resource: IResource) {
this.resource = resource;
this.creationStack = captureStackTrace();
}

public resolve(context: IResolveContext): any {
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/cdk/lib/private/intrinsic.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IResolvable, IResolveContext } from "../resolvable";
import { captureStackTrace } from "../stack-trace";
import { Token } from "../token";
import { createStackTrace } from "./stack-trace";

/**
* Token subclass that represents values intrinsic to the target document language
Expand All @@ -25,7 +25,7 @@ export class Intrinsic implements IResolvable {
throw new Error(`Argument to Intrinsic must be a plain value object, got ${value}`);
}

this.creationStack = createStackTrace();
this.creationStack = captureStackTrace();
this.value = value;
}

Expand Down
5 changes: 4 additions & 1 deletion packages/@aws-cdk/cdk/lib/resolvable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ export interface IResolvable {
/**
* The creation stack of this resolvable which will be appended to errors
* thrown during resolution.
*
* If this returns an empty array or `undefined` the stack will not be
* attached.
*/
readonly creationStack?: string[];
readonly creationStack: string[] | undefined;

/**
* Produce the Token's value at resolution time
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// tslint:disable-next-line:ban-types
export function createStackTrace(below?: Function): string[] {
below = below || createStackTrace; // hide myself if nothing else
export function captureStackTrace(below?: Function): string[] {
below = below || captureStackTrace; // hide myself if nothing else
const object = { stack: '' };
const previousLimit = Error.stackTraceLimit;
try {
Expand Down
3 changes: 3 additions & 0 deletions packages/@aws-cdk/cdk/test/test.tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,8 @@ export = {
};

class Promise2 implements IResolvable {
public readonly creationStack = [];

public resolve() {
return {
Data: {
Expand All @@ -614,6 +616,7 @@ class Promise2 implements IResolvable {
}

class Promise1 implements IResolvable {
public readonly creationStack = [];
public p2 = [ new Promise2(), new Promise2() ];

public resolve() {
Expand Down