ballerina-platform / ballerina-library

The Ballerina Library
https://ballerina.io/learn/api-docs/ballerina/
Apache License 2.0
135 stars 56 forks source link

The ballerina project crashes without giving a proper error message for associated entities containing defaultable fields #6392

Open sahanHe opened 8 months ago

sahanHe commented 8 months ago

Description: When tried to generate the clients for the following model, the project crashes without giving the expected error output.

import ballerina/persist as _;

public type Phone record {|
    readonly string id;
    boolean sms = true;
|};

public type Person record {|
    readonly string id;
    Phone[] phones;
|};

The crash log looks like following:

SEVERE {b7a.log.crash} - The compiler extension in package 'ballerina:persist:1.2.0' failed to complete. class io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode cannot be cast to class io.ballerina.compiler.syntax.tree.RecordFieldNode (io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode and io.ballerina.compiler.syntax.tree.RecordFieldNode are in unnamed module of loader 'app') 
io.ballerina.projects.ProjectException: The compiler extension in package 'ballerina:persist:1.2.0' failed to complete. class io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode cannot be cast to class io.ballerina.compiler.syntax.tree.RecordFieldNode (io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode and io.ballerina.compiler.syntax.tree.RecordFieldNode are in unnamed module of loader 'app')
        at io.ballerina.projects.SyntaxNodeAnalysisTask.perform(SyntaxNodeAnalysisTask.java:62)
        at io.ballerina.projects.SyntaxTreeVisitor.runAnalysisTasks(SyntaxTreeVisitor.java:93)
        at io.ballerina.projects.SyntaxTreeVisitor.visitSyntaxNode(SyntaxTreeVisitor.java:80)
        at io.ballerina.compiler.syntax.tree.NodeVisitor.visit(NodeVisitor.java:43)
        at io.ballerina.projects.SyntaxTreeVisitor.runAnalysisTasks(SyntaxTreeVisitor.java:68)
        at io.ballerina.projects.SyntaxNodeAnalysisTaskRunner.runTasks(SyntaxNodeAnalysisTaskRunner.java:76)
        at io.ballerina.projects.SyntaxNodeAnalysisTaskRunner.runTasks(SyntaxNodeAnalysisTaskRunner.java:59)
        at io.ballerina.projects.SyntaxNodeAnalysisTaskRunner.runTasks(SyntaxNodeAnalysisTaskRunner.java:51)
        at io.ballerina.projects.CodeAnalyzerManager.runSyntaxNodeAnalysisTasks(CodeAnalyzerManager.java:108)
        at io.ballerina.projects.CodeAnalyzerManager.runCodeAnalyzerTasks(CodeAnalyzerManager.java:61)
        at io.ballerina.projects.PackageCompilation.compile(PackageCompilation.java:118)
        at io.ballerina.projects.PackageCompilation.from(PackageCompilation.java:94)
        at io.ballerina.projects.PackageContext.getPackageCompilation(PackageContext.java:223)
        at io.ballerina.projects.Package.getCompilation(Package.java:146)
        at io.ballerina.persist.utils.BalProjectUtils.validateSchemaFile(BalProjectUtils.java:114)
        at io.ballerina.persist.cmd.Generate.execute(Generate.java:153)
        at java.base/java.util.Optional.ifPresent(Optional.java:178)
        at io.ballerina.cli.launcher.Main.main(Main.java:58)
Caused by: java.lang.ClassCastException: class io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode cannot be cast to class io.ballerina.compiler.syntax.tree.RecordFieldNode (io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode and io.ballerina.compiler.syntax.tree.RecordFieldNode are in unnamed module of loader 'app')
        at io.ballerina.stdlib.persist.compiler.PersistModelDefinitionValidator.reportMandatoryCorrespondingFieldDiagnostic(PersistModelDefinitionValidator.java:773)
        at io.ballerina.stdlib.persist.compiler.PersistModelDefinitionValidator.validateRelation(PersistModelDefinitionValidator.java:546)
        at io.ballerina.stdlib.persist.compiler.PersistModelDefinitionValidator.validateEntityRelations(PersistModelDefinitionValidator.java:466)
        at io.ballerina.stdlib.persist.compiler.PersistModelDefinitionValidator.perform(PersistModelDefinitionValidator.java:191)
        at io.ballerina.stdlib.persist.compiler.PersistModelDefinitionValidator.perform(PersistModelDefinitionValidator.java:112)
        at io.ballerina.projects.SyntaxNodeAnalysisTask.perform(SyntaxNodeAnalysisTask.java:46)
        ... 17 more

When the association between entities is removed, the expected log message can be observed

ERROR: failed to generate types and client for the definition file(model.bal). the model definition file(model.bal) has errors.
ERROR [model.bal:(5:5,5:24)] an entity does not support defaultable field

Affected Product Version: ballerina swan lake 2201.8.x

niveathika commented 8 months ago

Its' better if we can catch any throwable and log it similar to how ballerina logs unexpected errors. This improves user experience vastly.

@daneshk WDYT?