Skip to content

Formatted lines with 80 characters, null crash fix, English fixes #144

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

Merged

Conversation

noordawod
Copy link
Contributor

In a production app I used get_it and I had a crash with the nullsafety branch. Turns out that isRegistered() calls _findFactoryByNameAndType() which throws an exception because the returned value is null, but is silenced using the bang (!) character.

So I fixed that and also reformatted the source code to 100 characters per line (it was not formatted it seemed). Also, many English grammatical and pronunciation errors were fixed.

' type ${T.toString()} is not registered inside GetIt. '
'\n(Did you accidentally do GetIt sl=GetIt.instance(); instead of GetIt sl=GetIt.instance;'
'\nDid you forget to register it?)',
);

return instanceFactory!;
Copy link
Contributor Author

@noordawod noordawod Jan 1, 2021

Choose a reason for hiding this comment

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

This line caused a hard crash in a production app because assert() did not run. In general, use of ! is discouraged and one should find an alternative to yield the eventual logic.

In this case, for example, one can use throwIf() which is guaranteed to run in production.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I disagree, if you your crash wasn't caught during debug something is wrong how you test your code and normally you always have some gloabl execption handler that logs such cases.
Also you didn't change the assert. How did you fix the problem?

@noordawod noordawod changed the title Bugfixes formatting Formatted lines with 100 characters, null crash fix, English fixes Jan 1, 2021
@noordawod
Copy link
Contributor Author

Anybody here? @escamoteur?

@escamoteur
Copy link
Collaborator

escamoteur commented Jan 7, 2021 via email

@noordawod
Copy link
Contributor Author

Reminder @escamoteur

Copy link
Collaborator

@escamoteur escamoteur left a comment

Choose a reason for hiding this comment

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

Hi,
thanks for your PR.
My problem is, that it was intentional that the line length was set to 80, because pub's rating system punishes you if you use another length. Don't know if they have changed it. As this is a prerelease we probably can try.
Please see my other comments.
cheers
Thomas

@@ -0,0 +1,10 @@
root = true
Copy link
Collaborator

Choose a reason for hiding this comment

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

fot which editor it this config 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.

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 see you're working in VSCode. I work in IntelliJ IDEA. The beauty of .editorconfig is that it's cross-IDE and most IDEs out there can understand it and follow its configuration.

' type ${T.toString()} is not registered inside GetIt. '
'\n(Did you accidentally do GetIt sl=GetIt.instance(); instead of GetIt sl=GetIt.instance;'
'\nDid you forget to register it?)',
);

return instanceFactory!;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I disagree, if you your crash wasn't caught during debug something is wrong how you test your code and normally you always have some gloabl execption handler that logs such cases.
Also you didn't change the assert. How did you fix the problem?

@noordawod
Copy link
Contributor Author

noordawod commented Jan 7, 2021

I can reformat with 80 characters, no worries.

Regarding the crash: If you notice I added a couple of new methods and then used them in isRegistered() in order NOT to crash the app.

  /// Tests if an [instance] of an object or aType [T] or a name [instanceName]
  /// is registered inside GetIt
  @override
  bool isRegistered<T extends Object>({
    Object? instance,
    String? instanceName,
  }) {
    if (instance != null) {
      return _findFirstFactoryByInstanceOrNull(instance) != null;
    } else {
      return _findFirstFactoryByNameAndTypeOrNull<T>(instanceName) != null;
    }
  }

Today, isRegistered() calls _findFactoryByNameAndType() which returns a non-null value (that's why I didn't change it). But that causes isRegistered() to crash if that dependency isn't registered yet.

@noordawod noordawod changed the title Formatted lines with 100 characters, null crash fix, English fixes Formatted lines with 80 characters, null crash fix, English fixes Jan 7, 2021
@noordawod
Copy link
Contributor Author

@escamoteur reformatted the code to be 80 characters using flutter format.

@escamoteur
Copy link
Collaborator

Hi,

please never do a reformating and a shcnage in the same PR. I couldn't spot your changes because the diff is all red because of the reformatting.
Why did you add new methods instead of just use an throwIf isntead of the assert?
I'm trying to keep the null save version as close to the last official one as possible.

@noordawod
Copy link
Contributor Author

Forget it. This is the most inhospitable repo on the planet, I'm changing DI.

@noordawod noordawod closed this Jan 8, 2021
@escamoteur
Copy link
Collaborator

Sorry if you call it inhospital to ask reasonable question.
do what yyou want.

@noordawod
Copy link
Contributor Author

Why did you add new methods instead of just use an throwIf isntead of the assert?

I explained twice already. Re-read.

@escamoteur
Copy link
Collaborator

I just reread the whole converstion and you didn't. You proposed at the beginning we could use ´throwIf´but then you went for another solution without any explanation.

@noordawod
Copy link
Contributor Author

noordawod commented Jan 8, 2021

3rd time is charm maybe... repeating:

Regarding the crash: If you notice I added a couple of new methods and then used them in isRegistered() in order NOT to crash the app.

  /// Tests if an [instance] of an object or aType [T] or a name [instanceName]
  /// is registered inside GetIt
  @override
  bool isRegistered<T extends Object>({
    Object? instance,
    String? instanceName,
  }) {
    if (instance != null) {
      return _findFirstFactoryByInstanceOrNull(instance) != null;
    } else {
      return _findFirstFactoryByNameAndTypeOrNull<T>(instanceName) != null;
    }
  }

Today, isRegistered() calls _findFactoryByNameAndType() which returns a non-null value (that's why I didn't change it). But that causes isRegistered() to crash if that dependency isn't registered yet.

I'll simplify more:

Current code in PROD:

  • The app starts and T isn't registered yet.
  • You call isRegistered<T>()
  • isRegistered() delegates to _findFactoryByNameAndType<T>()
  • _findFactoryByNameAndType() crashes because T is not registered yet.
  • The crash happens in PROD because assert() never runs, and the method ends with return instanceFactory! which is an ErrorinstanceFactory is not registered yet so it's null.

Proposed fix:

  • The app starts and T isn't registered yet.
  • You call isRegistered<T>()
  • isRegistered() delegates either to _findFirstFactoryByInstanceOrNull<T>() or _findFirstFactoryByNameAndTypeOrNull<T>().
  • These two methods are new in the proposed fix, they do not crash if T isn't registered.
  • isRegistered() returns the correct result, without crashing.

I hope this clears things up now?

@noordawod noordawod reopened this Jan 8, 2021
@escamoteur
Copy link
Collaborator

I totally got that. My question was why not just change the assert to a ´throwIf´ then isRegistered would work as expected?

@noordawod
Copy link
Contributor Author

I totally got that. My question was why not just change the assert to a ´throwIf´ then isRegistered would work as expected?

I believe it would work because isRegistered has a try-catch clause. It's in line with how the code is currently written, so I'm fine with patching it. This will also keep everything else intact, just how you like it ;)

Closing this pr.

@noordawod noordawod closed this Jan 9, 2021
@noordawod
Copy link
Contributor Author

ps: there were some English grammatical fixes but you can do that at your leisure.

@escamoteur
Copy link
Collaborator

Would love to only how to filter them out of the formatting?

@escamoteur escamoteur reopened this Jan 10, 2021
@escamoteur escamoteur merged commit 23b01ac into fluttercommunity:null_safety Jan 10, 2021
@noordawod
Copy link
Contributor Author

Glad this got merged! I think it was a good call.

@noordawod noordawod deleted the bugfixes_formatting branch January 10, 2021 15:04
@escamoteur
Copy link
Collaborator

Did you run the tests after the changes? Because here they failed after the merge.

You did forget to pass T from _findFactoryByTypeAndName to your _findFirstFactoryOrNull

@escamoteur
Copy link
Collaborator

Thanks again for your effort. After I copied the latest version from your PR into a new branch locally I could easier follow what you had changed.

@noordawod
Copy link
Contributor Author

Right, good! Will you fix the issue with passing T?

@escamoteur
Copy link
Collaborator

Already done and new versions on pub

@noordawod
Copy link
Contributor Author

Thanks @escamoteur, this has been a good experience :)

@escamoteur
Copy link
Collaborator

I accept this as an apology ;-)

@noordawod
Copy link
Contributor Author

Might as well :)

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