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

#2043 introduce ValidationErrorNoStack class to improve error creation performance #2142

Merged
merged 5 commits into from
Mar 6, 2024

Conversation

tedeschia
Copy link
Contributor

This Pull Request introduces ValidationErrorNoStack, a class aimed at enhancing performance in error validation processes. Similar to ValidationError, it does not extend from Error and avoids capturing the stack trace. This approach significantly improves efficiency, particularly for validations of large arrays.

Key Features:

  • New ValidationErrorNoStack Class: Implements the ValidationError interface, but without stack trace capturing.
  • Conditional Selection:
    • disableStackTrace = false: Retains ValidationError, standard behavior including stack trace.
    • disableStackTrace = true: Switches to ValidationErrorNoStack, optimizing performance by skipping stack trace capture.

Benefits:

  • Marked improvement in performance for extensive validations.
  • Maintains backward compatibility; default disableStackTrace = false ensures existing functionality is unaffected.

This update provides an efficient solution for intensive validation scenarios while preserving the functionality for current users.


Comment on lines 42 to 63
this.name = 'ValidationError';
this.value = value;
this.path = field;
this.type = type;

this.errors = [];
this.inner = [];

toArray(errorOrErrors).forEach((err) => {
if (ValidationError.isError(err)) {
this.errors.push(...err.errors);
const innerErrors = err.inner.length ? err.inner : [err];
this.inner.push(...innerErrors);
} else {
this.errors.push(err);
}
});

this.message =
this.errors.length > 1
? `${this.errors.length} errors occurred`
: this.errors[0];
Copy link
Owner

Choose a reason for hiding this comment

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

Can we DRY this up by moving it to a function, and just put the implementation of ValidationErrorNoStack in this file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm trying to figure out how to resolve this comment, but don't find the way!
If I move the initialization of class members to a function, outside the constructor, typescript complains that non-nullable members aren't initialized:
"Property 'errors' has no initializer and is not definitely assigned in the constructor"

Do you have any idea in mind to put me on track to solve this issue?

src/schema.ts Outdated
undefined,
disableStackTrace,
),
disableStackTrace
Copy link
Owner

Choose a reason for hiding this comment

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

Lets not do this ever place someone needs an error. I think we can do a combo of the original thought here, and pass the disableStackTrace option into the error constructor and then do

class ValidationError extends Error {
  constructor(
    errorOrErrors: string | ValidationError | readonly ValidationError[],
    value?: any,
    field?: string,
    type?: string,
    disableStack?: boolean
  ) {
      if (disableStack) {
        return new ValidationErrorNoStack()
      }  
    
    ...
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I can't go this way. If I use a return at the beginning of the constructor, I get typescript errors for all non-nullable members, for example:
Property 'errors' is used before being assigned

If you don't like selecting which ValidationError version to construct everywhere, I could define a factory function that receives all args and returns ValidationError or ValidationErrorNoStack depending on disableStack arg.

What do you think?

@jquense
Copy link
Owner

jquense commented Feb 27, 2024

@tedeschia
Copy link
Contributor Author

tedeschia commented Mar 4, 2024

@jquense great! I have adopted your proposal, made a minor fix (setting "type" prop on ValidationError constructor), updated the project using the consolidated ValidationError class and fixing some tests.
Are we OK to merge the changes now?

@jquense jquense merged commit f294613 into jquense:master Mar 6, 2024
1 check passed
@jquense
Copy link
Owner

jquense commented Mar 6, 2024

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants