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

Task/294 task run checkproperties on config load #324

Draft
wants to merge 19 commits into
base: develop
Choose a base branch
from

Conversation

DougMidgley
Copy link
Contributor

@DougMidgley DougMidgley commented May 19, 2022

PR details

What is the purpose of this pull request?

  • Other, please explain: Internal

What changes did you make? (Give an overview)

rework loading parameters logic into a new class to help reduce circular dependencies and remove bloat in common classes

Is there anything you'd like reviewers to focus on?

initial stab - feedback requested more generally about approach

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • ESLint & Prettier are not outputting errors or warnings
  • README.md updated (if applicable)
  • CHANGELOG.md updated
  • ran npm run docs to update developer docs

@DougMidgley DougMidgley linked an issue May 19, 2022 that may be closed by this pull request
@JoernBerkefeld
Copy link
Contributor

Wrong target? ;)

douglas.midgley added 2 commits May 22, 2022 22:24
…into task/294-task-run-checkproperties-on-config-load

# Conflicts:
#	lib/util/file.js
#	lib/util/util.js
@DougMidgley DougMidgley changed the base branch from main to develop May 22, 2022 20:29
@DougMidgley DougMidgley marked this pull request as ready for review May 22, 2022 20:30
Copy link
Contributor

@JoernBerkefeld JoernBerkefeld left a comment

Choose a reason for hiding this comment

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

good idea, needs a few tests & tweaks though

lib/util/cli.js Outdated Show resolved Hide resolved
Comment on lines -46 to -61
properties = properties || File.loadConfigFile();
if (!(await Util.checkProperties(properties))) {
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

the return null case is no longer executed. If the config is missing or bad this method would continue (and then eventually fail).

With a few tweaks your new Config.getProperties could at least throw an error or return null. It's calling checkProperties internally but not testing its return value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

would it work to use throw error in checkProperties, can also add missing fields as an error property for that use that. I think that would clean up a couple of things

Comment on lines -64 to -78
if (!(await Util.checkProperties(properties))) {
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

the return null case is no longer executed. If the config is missing or bad this method would continue (and then eventually fail).

With a few tweaks your new Config.getProperties could at least throw an error or return null. It's calling checkProperties internally but not testing its return value.

lib/util/config.js Outdated Show resolved Hide resolved
lib/index.js Show resolved Hide resolved
lib/util/cli.js Outdated Show resolved Hide resolved
lib/util/cli.js Outdated
@@ -85,7 +86,7 @@ const Cli = {
*/
async getCredentialObject(properties, target, isCredentialOnly, allowAll) {
try {
if (!(await Util.checkProperties(properties))) {
if (!(await Config.checkProperties(properties))) {
Copy link
Contributor

Choose a reason for hiding this comment

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

does this logic still work, given that you run checkProperties inside of getProperties already?

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 assume you mean, is it needed? I would say actually no, so we can throw errors earlier on getProperties?

douglas.midgley added 3 commits June 19, 2022 11:52
…into task/294-task-run-checkproperties-on-config-load

# Conflicts:
#	docs/dist/documentation.md
#	lib/cli.js
#	lib/index.js
#	lib/util/businessUnit.js
#	lib/util/file.js
#	lib/util/init.js
#	lib/util/util.js
Copy link
Contributor

@JoernBerkefeld JoernBerkefeld left a comment

Choose a reason for hiding this comment

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

lots still to do here. I'd ask that we please follow through with my PRs first and once this reaches production readiness I'd happily adjust to the new reality.

our tool has to work properly and have reasonably nice error output for users in a CLI. Therefore, we cannot just throw errors without handling them. Prefixing our errors with "Retrieve failed: ...", "Document failed: ...." is also not very user friendly. For one, the user just executed that command. whatelse should have failed? Therefore, whatever error message comes needs to be printable as is - and I've gone through great lengths to make that happen over the past months.

The few times you added try-catch blocks seem like a step back in that regard. For the many other lines on which you had to replace getting the config, error handling is just missing and would result in ugly stack traces being presented to our already not-so-CLI-friendly user base.

To get this ready for merge you'd have to either go back on your change concerning the return value of the config getter - a simple refactoring would have also done us a favor without causing the need to retest every single method just because of this PR alone - or you consistently handle potential errors caused by your new code gracefully in either lib/index.js or in lib/cli.js.

please note the 11+ hidden conversations

if (silent) {
const err = new Error('Missing Fields');
err.missingFields = missingFields;
throw err;
Copy link
Contributor

Choose a reason for hiding this comment

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

how is this "silent"?

silent was clearly marked as the mode we use to process the results outside of this method - after returning an array of strings (which you still have in the jsdoc for this method)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so, i think we need to improve consistency on "silent". Currently I can see some cases where it means no CLI messages and others where it means no interaction (no inquirer commands). In particular, for this case, the one location that uses missingFields has a try/catch block around to pick these up correctly.
Additional point, I might wanna do is merge/split differently the checkProps and getProps methods to ensure checks contains ALL the checks and get is just the high level loading -> thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

this feels like a "lets sit at the same desk and talk" topic

Copy link
Contributor

Choose a reason for hiding this comment

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

went through the code again but cant help but think that wrapping this in an error adds no value here. It does add extra lines of code though and complexity. we can argue about renaming the parameter "silent" to "returnList" or sth like it but that's really the expected outcome here and while it's true that you could do that with try-catch and attaching it to the error, there are probably also 20 other ways but none are better than simply returning the array that the other method is looking for here.

Comment on lines 244 to 248
if (responses.runUpgradeNow) {
// use _execSync here to avoid a circular dependency
this.execSync('mcdev', ['upgrade']);
}
throw new Error(errorMsgOutput);
Copy link
Contributor

Choose a reason for hiding this comment

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

why should we print errors after running mcdev upgrade?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

previously this returned false - which would fail the check. Basically took this over - it probably should just be removed now, agree?

Copy link
Contributor

Choose a reason for hiding this comment

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

after we've run mcdev we should end execution. we COULD continue automatically but ensuring that this runs smoothly then might just not be worth the effort

lib/index.js Show resolved Hide resolved
lib/index.js Show resolved Hide resolved
lib/index.js Outdated Show resolved Hide resolved
lib/Builder.js Show resolved Hide resolved
lib/Builder.js Show resolved Hide resolved
lib/Builder.js Show resolved Hide resolved
lib/Deployer.js Show resolved Hide resolved
lib/Deployer.js Outdated Show resolved Hide resolved
douglas.midgley added 5 commits June 28, 2022 22:15
…into task/294-task-run-checkproperties-on-config-load

# Conflicts:
#	docs/dist/documentation.md
#	lib/Deployer.js
#	lib/cli.js
…into task/294-task-run-checkproperties-on-config-load
…into task/294-task-run-checkproperties-on-config-load

# Conflicts:
#	docs/dist/documentation.md
lib/cli.js Outdated
@@ -374,6 +374,10 @@ yargs
})
.demandCommand(1, 'Please enter a valid command')
.strict()
.fail((_, err) => {
Util.logger.error(err.message);
process.exit(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

our adaption of Util.logger.error already sets the exit code to 1

Copy link
Contributor

Choose a reason for hiding this comment

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

error: function (msg) {

Copy link
Contributor

@JoernBerkefeld JoernBerkefeld Jun 30, 2022

Choose a reason for hiding this comment

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

also there is a method to wrap around exit code 1:

signalFatalError() {

apparently the right way to do it for async-functions was process.exitCode = 1;
here more on the why: https://nodejs.dev/learn/how-to-exit-from-a-nodejs-program

lib/index.js Outdated
Comment on lines 311 to 314
if (type && !MetadataTypeInfo[type]) {
Util.logger.error(`:: '${type}' is not a valid metadata type`);
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

should be done before getting the config to increase speed of execution.
also, given that this is highest level execution - should we not switch the error log into a throw error instead?

lib/index.js Outdated
Comment on lines 327 to 331
Util.logger.error('mcdev.document ' + ex.message);
Util.logger.debug(ex.stack);
Util.logger.info(
'If the directoy does not exist, you may need to retrieve this BU first.'
);
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe throw error instead given the new catch in cli.js?

@JoernBerkefeld JoernBerkefeld added the chore Jira issue-type "Task" label Jul 1, 2022
@JoernBerkefeld JoernBerkefeld added this to the 4.0.0 milestone Jul 1, 2022
* @param {boolean} [silent] omit throwing errors and print messages; assuming not silent if not set
* @returns {object} central properties object
*/
async getProperties(silent) {
Copy link
Contributor

Choose a reason for hiding this comment

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

note - this is how we define methods in other util classes

* @param {boolean} [silent] set to true for internal use w/o cli output
* @returns {Promise.<boolean | string[]>} file structure ok OR list of fields to be fixed
*/
checkProperties: async function (properties, silent) {
Copy link
Contributor

Choose a reason for hiding this comment

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

here you switch to a different notation. any reason?

*
* @returns {object} default properties
*/
getDefaultProperties: async function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

and again the other type of notation.
this sets a property to an anonymous method rather than define the method getDefaultProperties as part of the Config object

* @returns {object} central properties object
*/
async getProperties(silent) {
async getProperties(skipChecks = false) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

again, i would say withChecks = true here to avoid double negatives. https://blog.devgenius.io/code-smell-51-double-negatives-993b6160f3e1

@JoernBerkefeld JoernBerkefeld modified the milestones: 4.0.0, 4.1.0 Jul 4, 2022
@JoernBerkefeld
Copy link
Contributor

moving this out of 4.0.0. it's a waste of time at this point.
suggesting to re-do the PR only with the purpose of reducing file system reads which is actually a great idea.

but without changing the error-recognition & reporting logic (exception vs boolean return)

@JoernBerkefeld JoernBerkefeld marked this pull request as draft July 4, 2022 13:53
@JoernBerkefeld JoernBerkefeld modified the milestones: 4.2.0 , 4.3.0 Nov 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore Jira issue-type "Task"
Projects
Status: In Review
Development

Successfully merging this pull request may close these issues.

[TASK] Run checkProperties on Config Load
2 participants