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

Use optionals for return values that may be null to enforce a client check #2141

Open
gok99 opened this issue Mar 3, 2024 · 0 comments
Open

Comments

@gok99
Copy link
Contributor

gok99 commented Mar 3, 2024

What feature(s) would you like to see in RepoSense

A large number of getter functions have optional return semantics - the return value might be null if the field is uninitialized or not applicable. The problem is often that it's hard to know if a check is necessary without having the client know about the underlying details of the initialization logic.

Path authorConfigFilePath = cliArguments.getAuthorConfigFilePath();
Path groupConfigFilePath = cliArguments.getGroupConfigFilePath();
if (authorConfigFilePath != null && Files.exists(authorConfigFilePath)) {
try {
authorConfigs = new AuthorConfigCsvParser(cliArguments.getAuthorConfigFilePath()).parse();
RepoConfiguration.merge(repoConfigs, authorConfigs);
RepoConfiguration.setHasAuthorConfigFileToRepoConfigs(repoConfigs, true);
} catch (IOException | InvalidCsvException e) {
// for all IO and invalid csv exceptions, log the error and continue
logger.log(Level.WARNING, e.getMessage(), e);
}
}
if (groupConfigFilePath != null && Files.exists(groupConfigFilePath)) {
try {
groupConfigs = new GroupConfigCsvParser(cliArguments.getGroupConfigFilePath()).parse();
RepoConfiguration.setGroupConfigsToRepos(repoConfigs, groupConfigs);
} catch (IOException | InvalidCsvException e) {
// for all IO and invalid csv exceptions, log the error and continue
logger.log(Level.WARNING, e.getMessage(), e);
}
}

Not all nulls necessarily bad however. In some cases like this:

public void removeIgnoredAuthors(List<String> ignoredAuthorsList) {
for (String author : ignoredAuthorsList) {
Author authorToRemove = null;
if (authorEmailsToAuthorMap.containsKey(author)) {
authorToRemove = authorEmailsToAuthorMap.get(author);
} else if (authorNamesToAuthorMap.containsKey(author.toLowerCase())) {
authorToRemove = authorNamesToAuthorMap.get(author.toLowerCase());
}
if (authorToRemove != null) {
removeAuthorInformation(authorToRemove);
}
}
}

the scope of the nulls are only within a function, which does not suffer from the same issue of having to reason about the presence of a value.

Java Optionals are a good way to deal with this pattern, by enforcing a client check when a return value may not be present. This has both the effects of minimizing programmer error and helping document the intended nature of function return values. Ideally, return values that are not Optional are guaranteed to be present.

While this problem is not limited to getter functions, this would be a good place to start this refactor, and consider other instances on a case-by-case basis.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

2 participants