question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

CDK for .NET does not use the compiler to flag construct required properties

See original GitHub issue

I am using the CDK version 0.24.1 with c#. If I create a stack that contains this:

new Amazon.CDK.AWS.Lambda.Function(this, "SomeId", new FunctionProps());

It compiles perfectly. But then, when I run cdk diff, I get the following error:

Unhandled Exception: Amazon.JSII.Runtime.JsiiException: Cannot read property 'name' of undefined
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Deputy.DeputyBase..ctor(DeputyProps props)

So two problems here:

  1. The error message does not say anything useful. It is pretty hard to know which construct is causing the error.
  2. The error is caused by the fact that I didn’t provide the required FunctionProps properties to my lambda. The required function properties are handler, code and runtime.

I’d like to focus on the second point. The fact that we get a runtime error and not a compile time error is a big lost compared to TypeScript. In TypeScript, if I don’t provide a required property, I see it directly in my IDE:

image

Given that C# is a compiled language, I would expect that all required properties be enforced at compile time.

In my opinion, the way to do this is simply to use constructor for the different props. For example, the FunctionProps is currently defined like this:

public class FunctionProps : DeputyBase, IFunctionProps
{
   // The class just has a default/empty constructor
   public FunctionProps() {}
   // These 3 properties are required but there is no way to differentiate 
   // them from optional properties from the compiler point of view.
   public string Handler { get; set; }
   public Code Code { get; set; }
   public Runtime Runtime { get; set; }
   // All other properties are optional
   public string FunctionName { get; set; }
}

My suggestion would be to use a constructor with parameters instead of relying on getters/setters. Ex:

public class FunctionProps : DeputyBase, IFunctionProps
{
    public FunctionProps(
        // Required parameters come first and don't have default values.
        string handler,
        Code code,
        Runtime runtime,
        // Optional parameters come second and *DO* have default values
        string functionName = null)
    {
        Handler = handler;
        Code = code;
        Runtime = runtime;
        FunctionName = functionName;
    }

    // Required properties
    public string Handler { get; set; }
    public Code Code { get; set; }
    public Runtime Runtime { get; set; }
    // Optional properties
    public string FunctionName { get; set; }
}

With such code, I get a nice intellisense that tells me what is required and what is optional:

image

And if I instantiate a FunctionProps and don’t provide the required properties, I get a compile time error:

error CS7036: There is no argument given that corresponds to the required formal parameter 'handler' of 'FunctionProps.FunctionProps(string, Code, Runtime, string)'

And finally here’s how it looks like when I define a lambda.

new Amazon.CDK.AWS.Lambda.Function(this, "SomeId", new FunctionProps(
    handler: "my handler",
    code: Code.Inline("my code"),
    runtime: Runtime.NodeJS810,
    // Optional parameters below: since they have default 
    // values in the constructor, I can omit specifying them.
    //
    // I use a named parameter here but I could also have used 
    // the property setter. It's just a matter of preference.
    // Personally, I prefer to use named constructor parameters 
    // for the optional parameters since they end up at the same 
    // indentation level as the required parameters.
    functionName: "SomeName");

Please let me know what you think of this proposition.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
costleyacommented, Mar 21, 2019

My take is to replace them with keyword arguments. We can definitely do this when we start doing some work on the generator. We’ll try to schedule to do this work sometime in April or May.

0reactions
assyadhcommented, Aug 5, 2019

Related to https://github.com/aws/jsii/issues/210

Adding the roslyn analyser should fix this.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Working with the AWS CDK in C# - AWS Cloud Development ...
The .NET ecosystem uses the NuGet package manager. The main CDK package, which contains the core classes and all stable service constructs, is...
Read more >
Native AOT deployment overview - .NET | Microsoft Learn
Native AOT apps don't use a Just-In-Time (JIT) compiler when the application runs. Native AOT apps can run in restricted environments where ...
Read more >
@aws-cdk/assert | Yarn - Package Manager
The AWS Cloud Development Kit (AWS CDK) is an open-source software development framework to define cloud infrastructure in code and provision it through...
Read more >
Build Times, Bundle Sizes, and Other Improvements Made by ...
However, the Angular team has made it possible to still use the View ... The Ivy compiler not only includes changes to improve...
Read more >
Bug listing with status CONFIRMED as at 2022/12/25 22:46:30
NET (New package)" status:CONFIRMED resolution: severity:normal ... Bug:220331 - "Please make package.use USE flags overrides looking different from ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found