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

[ecmascript] (#311) Fix for Unknown error on VROES.import from a missing/invalid module path #345

Merged
merged 18 commits into from
Aug 19, 2024

Conversation

bcpmihail
Copy link
Contributor

@bcpmihail bcpmihail commented Jul 18, 2024

Description

Issue summary:
VROES.import(...).from(invalidModulePath) threw an Unknown error. Cause was calling System.getModule() with blank path.

Changes:
Added validation for module path and specifiers in ecmascript/Module, affecting for VROES.import().from().
Additional parameter for handling the validation errors in Module.import(), Module.load() with default value - function to log the error and return null (avoids breaking changes).
Removed unused path parameter and from() method from export.
Documentation (comments, README, release note)
Unit tests.

Checklist

  • I have added relevant error handling and logging messages to help troubleshooting
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation, relevant usage information (if applicable)
  • I have updated the PR title with affected component, related issue number and a short summary of the changes introduced
  • I have added labels for implementation kind (kind/) and version type (version/)
  • I have tested against live environment, if applicable
  • I have synced any structure and/or content vRA-NG improvements with vra-ng and ts-vra-ng archetypes (if applicable)
  • I have my changes rebased and squashed to the minimal number of relevant commits. Notice: don't squash all commits
  • I have added a descriptive commit message with a short title, including a Fixed #XXX - or Closed #XXX - prefix to auto-close the issue

Testing

Tested on a client environment with the same action as the issue and a library that searched through potential module paths.

Added more specific errors and default error handler (System.error).

Removed unused Module.require, Module.export parameter, minor fixes

Signed-off-by: Mihail Penchev (c) <[email protected]>
Renamed DEFAULT_ERR_HANDLER, minor formatting fix

Signed-off-by: Mihail Penchev (c) <[email protected]>
@bcpmihail bcpmihail self-assigned this Jul 18, 2024
@bcpmihail bcpmihail requested a review from a team as a code owner July 18, 2024 08:31
@bcpmihail bcpmihail linked an issue Jul 18, 2024 that may be closed by this pull request
@github-actions github-actions bot added the kind/bug Something isn't working label Jul 18, 2024
@bcpmihail bcpmihail added lang/typescript Related to typescript code area/ecmascript Relates to ecmascript module labels Jul 18, 2024
}
moduleInfo = !path ? null : System.getModule(path);
if (!moduleInfo) {
throw new Error(`No action or module found for paths: '${path}', '${path}/index'!`);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could include moduleName, actionName as additional information to error message. In case of typos, strange chars, etc it could be helpful.

Copy link
Contributor Author

@bcpmihail bcpmihail Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path is included for that purpose. It is unknown whether an action or a module (namespace) is being imported.
The specifiers (elements to be imported from a module, or default/*) are validated separately

actionResult = invokeActionOrModule(path, onError);
}
catch (err) {
error = err?.message || err;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best approach is always to store whole Exception object, instead of error message property only.
Small chance at TS/JS but whole exception/error object may contains some additional information such as stackTrace or internal error details.

Because error variable has initial value string then (something like this):
.... catch(err){ error = err.toString(); }...

@Michaelpalacce
Copy link
Collaborator

You need to increase your test coverage for this. You've added functionality that was not tested.

@Michaelpalacce
Copy link
Collaborator

Passing the error handler for each function sounds like a bad idea. We won't really use Module directly in the first place either. We need to be opinionated with this class and handle errors our way.

Notes:

  1. Each function having a different error handler sounds like a poor idea
  2. Not apparent that it's an error handler for module import errors only
  3. Consider giving people error handling options... for example: throw on error or log on error instead
  4. Do global error handling, perhaps with some sort of a static setter

Copy link
Collaborator

@Michaelpalacce Michaelpalacce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more tests and move error handling away from each method

@VenelinBakalov VenelinBakalov added the version/patch The change is a non-breaking bugfix label Jul 30, 2024
@bcpmihail bcpmihail added the pr/wip This PR is still work in progress, added if we don't want the stale bot to auto close it label Aug 1, 2024
@bcpmihail
Copy link
Contributor Author

Merged latest changes from main (as a "chore" squashed commit)
Addressed PR comments (not yet tested, pending new env. creation; added pr/wip label):

  • Error handling moved from each method, only Module.load and import have error handling.
  • Standard options for module error-handling provided in an enum, custom error handler still supported.
  • Module error handler is set globally for Module/VROES (new setter), by default is System.error (doesn't throw)
  • updated unit tests (no new tests because there are no new public methods apart from a setter)
    Additional:
  • Added Regex validation for module/action path (w/ support for relative path in import)
  • minor refactoring - extracted methods
  • documentation updated and moved to interfaces

@vmwclabot
Copy link
Member

@bcpmihail, you must sign every commit in this pull request acknowledging our Developer Certificate of Origin before your changes are merged. This can be done by adding Signed-off-by: John Doe <[email protected]> to the last line of each Git commit message. The e-mail address used to sign must match the e-mail address of the Git author. Click here to view the Developer Certificate of Origin agreement.

1 similar comment
@vmwclabot
Copy link
Member

@bcpmihail, you must sign every commit in this pull request acknowledging our Developer Certificate of Origin before your changes are merged. This can be done by adding Signed-off-by: John Doe <[email protected]> to the last line of each Git commit message. The e-mail address used to sign must match the e-mail address of the Git author. Click here to view the Developer Certificate of Origin agreement.

@bcpmihail bcpmihail force-pushed the bugfix/issue-311-vroes-import-unknown-error branch from 89b654c to 16c50af Compare August 1, 2024 14:30
@bcpmihail
Copy link
Contributor Author

Tested successfully on an environment, small fix was required.

…ng options, regex validation

New enum with error handling options for the Module.load and import methods.
New method setModuleErrorHandler in VROES and Module, accepting enum option or custom error handler
Regex validation of action/module paths in Module.load/import
Module error handling will only be invoked at the public method (load/import) level (not recursively)

Signed-off-by: Mihail Penchev (c) <[email protected]>
    Enum export was causing issues with generated JS

Signed-off-by: Mihail Penchev (c) <[email protected]>
@bcpmihail bcpmihail force-pushed the bugfix/issue-311-vroes-import-unknown-error branch from 16c50af to 4ba47d7 Compare August 1, 2024 14:38
@vmwclabot
Copy link
Member

@bcpmihail, you must sign every commit in this pull request acknowledging our Developer Certificate of Origin before your changes are merged. This can be done by adding Signed-off-by: John Doe <[email protected]> to the last line of each Git commit message. The e-mail address used to sign must match the e-mail address of the Git author. Click here to view the Developer Certificate of Origin agreement.

1 similar comment
@vmwclabot
Copy link
Member

@bcpmihail, you must sign every commit in this pull request acknowledging our Developer Certificate of Origin before your changes are merged. This can be done by adding Signed-off-by: John Doe <[email protected]> to the last line of each Git commit message. The e-mail address used to sign must match the e-mail address of the Git author. Click here to view the Developer Certificate of Origin agreement.

@bcpmihail bcpmihail force-pushed the bugfix/issue-311-vroes-import-unknown-error branch from 4ba47d7 to 680b867 Compare August 1, 2024 14:40
@bcpmihail
Copy link
Contributor Author

Conflicts resolved. @Michaelpalacce @dimitar-nikolov-lazarov please review.

@VenelinBakalov
Copy link
Collaborator

@dimitar-nikolov-lazarov @Michaelpalacce whenever you have the chance to check

…ix/issue-311-vroes-import-unknown-error

Signed-off-by: Mihail Penchev (c) <[email protected]>
* - one of the predefined {@link DefaultModuleErrorHandlers} options
* Default is {@link DefaultModuleErrorHandlers.SYS_ERROR}
*/
setModuleErrorHandler(eh: DefaultModuleErrorHandlers | ModuleErrorHandler): void;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to be accepting a string or a function? It's breaking the "S" in SOLID.

/**
* Predefined handlers for errors on loading/importing a module or action - see {@link DefaultModuleErrorHandlers}
*/
const ModuleErrorHandlers = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I don't think this will ever change.. we give them a default and they can overwrite it if they want, imho

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Keeping only the System.error option as default (will also address #345 (comment) )

* Note - use of '-' and capital letters is not limited, despite not being recommended.
* Using non-capturing group (?:) to reduce overhead.
*/
const IMPORT_BASE_REGEX = /^(?:[\w-]+\.)*[\w-]+$/g;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets give examples for these regexes?

@@ -94,6 +205,7 @@ export interface ModuleElementList {
return this;
};

/** @deprecated - unused and not part of {@link ModuleExport} */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deprecations should happen after an internal triage, lets add this to the roadmap to discuss?

* @throws Error if the relative path goes too many steps back (via ../) in the base path
*/

function constructAbsolutePath(path: string, base: string): string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be extensively unit tested. What I mean here: ONLY this method needs to be unit tested. With a data provider that will have: path, base, expectedFailure, expected or sth like that

* @throws Error if there are no specifiers
* @throws Errir containing a list of invalid specifiers (blank, duplicate, missing from the provided module), if any.
*/
function extractImports(specifiers: string[], importedModule: any): any[] {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous comment about unit testing

…ault module error handler

Addressing PR comments - removed enum with module error handler options

Signed-off-by: Mihail Penchev (c) <[email protected]>
…emoved @deprecated

Pending discussion to re-add @deprecated for Module.Export.from`

Signed-off-by: Mihail Penchev (c) <[email protected]>
@bcpmihail bcpmihail force-pushed the bugfix/issue-311-vroes-import-unknown-error branch from 60aec81 to 5687f7c Compare August 19, 2024 07:13
@Michaelpalacce
Copy link
Collaborator

LGTM

…odule.constructAbsolutePath

Signed-off-by: Mihail Penchev (c) <[email protected]>
…odule.extractImports

Signed-off-by: Mihail Penchev (c) <[email protected]>
@bcpmihail bcpmihail merged commit dd57325 into main Aug 19, 2024
14 checks passed
@VenelinBakalov VenelinBakalov deleted the bugfix/issue-311-vroes-import-unknown-error branch August 19, 2024 11:08
@VenelinBakalov VenelinBakalov changed the title [ecmascript] (#311)Fix for Unknown error on VROES.import [ecmascript] (#311) Fix for Unknown error on VROES.import Aug 19, 2024
@VenelinBakalov VenelinBakalov changed the title [ecmascript] (#311) Fix for Unknown error on VROES.import [ecmascript] (#311) Fix for Unknown error on VROES.import from a missing/invalid module path Aug 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/ecmascript Relates to ecmascript module kind/bug Something isn't working lang/typescript Related to typescript code pr/wip This PR is still work in progress, added if we don't want the stale bot to auto close it version/patch The change is a non-breaking bugfix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

VROES.import from invalid package throws Unknown error
5 participants