Skip to content

tsoa crashes due to missing check in prettyTroubleCause #1706

@CodeSmith32

Description

@CodeSmith32

Sorting

  • I'm submitting a ...

    • bug report
    • feature request
    • support request
  • I confirm that I

    • used the search to make sure that a similar issue hasn't already been submit

Expected Behavior

It doesn't crash when running it.
(Our code is currently proprietary. Cannot release. Sorry.)

Current Behavior

tsoa crashes due to a missing check in prettyTroubleCause:
https://github.com/lukeautry/tsoa/blob/master/packages/cli/src/metadataGeneration/exceptions.ts#L37

This happens because, even though node.pos !== -1 is true, node.parent is undefined, and node.getText() relies on parent not being undefined.

Possible Solution

Adjust the line to check that node.parent is not falsy:

name = node.pos !== -1 && node.parent ? node.getText() : ((node as any).name?.text || '<unknown name>');
//                     ^^ ^^^^^^^^^^^

Steps to Reproduce

I'm not sure I'm able to determine all conditions under which this occurs, but it appears to occur when casting to a namespaced type within an object returned by a controller method. The following minimal code appears to trip this condition:

import { Controller, Post, Route } from "tsoa";

namespace Foo {
  export interface Bar {
    x: number;
    y: number;
  }
}

@Route("/some/endpoint")
class TestController extends Controller {
  @Post("/some/endpoint")
  async someEndpoint() {
    const thing = { x: 1, y: 2 };

    return {
      thing: thing as Foo.Bar,
    };
  }
}

export const testController = new TestController();

If node.pos should always be -1 when node.parent is undefined, then this may be an error in the TypeScript engine (TypeScript v5.6.3).

Context (Environment)

Version of the library: 6.5.1 (Worked fine in 5.1.1)
Version of NodeJS: v20.11.1

  • Confirm you were using yarn not npm: [ ] (Using npm)

Detailed Description

The error occurs in the typescript engine when node.getText() tries to find the highest parent that represents the source file, in order to get the whole text contents of the file. Because node.parent is undefined, it fails, as it appears to be separated from the tree.

Thus a check for node.parent resolves the issue:

name = node.pos !== -1 && node.parent ? node.getText() : ((node as any).name?.text || '<unknown name>');
//                     ^^ ^^^^^^^^^^^

With that said, the node does appear to have an original node property which is part of the tree. An alternative solution, therefore, could look like:

name = node.pos !== -1 && node.parent ? node.getText()
  : node.pos !== -1 && node.original?.parent ? node.original.getText()
  : ((node as any).name?.text || '<unknown name>');

Breaking change?

As this error is occurring only because of an attempt to generate an error message, I don't think such a change in the condition would be that crucial or breaking.

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueThis issue could be an easy PR for those looking to help contributehelp wanted

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions