Skip to content

Introduce FailFast utils to provide offensive programing #5373

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

TimoPtr
Copy link
Collaborator

@TimoPtr TimoPtr commented May 28, 2025

Summary

While developing sometimes we encounter places where it should never throw an exception but to add more safety this PR introduce a mechanism that will crash crash in DEBUG if this kind of issue are encounter. It makes the error important to investigate ASAP.

It is also useful for unlocking an issue that happen in prod but we don't know how to reproduce it.

The design is flexible so that if we want we can override it so that the errors are reported to Sentry for instance. We could also add an option for us to enable the crash on release too. It would be useful for developer to get the error when we are in production.

Checklist

  • New or updated tests have been added to cover the changes following the testing guidelines.
  • The code follows the project's code style and best_practices.
  • The changes have been thoroughly tested, and edge cases have been considered.
  • Changes are backward compatible whenever feasible. Any breaking changes are documented in the changelog for users and/or in the code for developers depending on the relevance.

Screenshots

In debug the application process is killed and you have this message in the logs
image

In release the application is kept alive and you have this message in the logs
image

Link to pull request in documentation repositories

User Documentation: home-assistant/companion.home-assistant#

Developer Documentation: home-assistant/developers.home-assistant#

Any other notes

I've catch two errors that we have on Sentry that we don't know yet how to reproduce.

@TimoPtr
Copy link
Collaborator Author

TimoPtr commented May 28, 2025

@jpelgrom @dshokouhi if we agree with the implementation I'm going to write a small documentation in the developer documentation explaining a bit more how and when to use it.

@TimoPtr TimoPtr requested review from jpelgrom, dshokouhi and bgoncal May 28, 2025 13:25
Copy link
Member

@bgoncal bgoncal left a comment

Choose a reason for hiding this comment

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

I would first test with a condition to only crash while in debug, just to have an amostrage of how often this may happen in the current app state, afterwards I totally support the approach you are proposing.

Have in mind that crashes are something we need to fix quicker because depending where they are it can be a total blocker for the user, considering Google's "speed" recently on review approval, I would take that into consideration.

@home-assistant
Copy link

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@home-assistant home-assistant bot marked this pull request as draft May 28, 2025 15:17
Copy link
Member

@bgoncal bgoncal left a comment

Choose a reason for hiding this comment

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

Approving based on our talk in slack, I missed that this will only happen in debug

@TimoPtr
Copy link
Collaborator Author

TimoPtr commented May 28, 2025

I would first test with a condition to only crash while in debug, just to have an amostrage of how often this may happen in the current app state, afterwards I totally support the approach you are proposing.

Have in mind that crashes are something we need to fix quicker because depending where they are it can be a total blocker for the user, considering Google's "speed" recently on review approval, I would take that into consideration.

Today it will only crash in DEBUG meaning only when a developer would provide an APK manually. In RELEASE the default is to catch the error and log it and continue. It could put the app in an undefined state but at least it would not crash there.

As it is state in the description I would like to have an opt-in feature in the app where ppl could agree to crash like in DEBUG. This could be useful for developers or user to give us more details. This PR is not covering this proposal.

@TimoPtr TimoPtr marked this pull request as ready for review May 28, 2025 16:49
@home-assistant home-assistant bot requested a review from bgoncal May 28, 2025 16:49
@jpelgrom
Copy link
Member

jpelgrom commented May 28, 2025

In release the application is kept alive and you have this message in the logs image

Regular users don't use logcat. I worry that this is too much formatting (trying to create a box) which gets in the way or is lost when reading/copying from the app's logs section.

Copy link
Member

@jpelgrom jpelgrom left a comment

Choose a reason for hiding this comment

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

if we agree with the implementation I'm going to write a small documentation in the developer documentation explaining a bit more how and when to use it.

Generally agreed this could be useful to have. Review comments are mostly small tweaks which shouldn't result in major changes that impact any documentation.

While developing sometimes we encounter places where it should never throw an exception but to add more safety this PR introduce a mechanism that will crash crash in DEBUG if this kind of issue are encounter.

Fail fast is not the only possible fix for that. "it should never throw" could also mean "it should always be caught (we expect this may produce exceptions)".

this.handler = handler
}

fun failWhen(condition: Boolean, message: () -> String) {
Copy link
Member

Choose a reason for hiding this comment

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

Should this function and both failOnCatch functions have a short description as they are the 'public API'? (One or two sentences, not a full paragraph!)

Comment on lines +54 to +55
The exception is ignored to avoid a crash but it should be handled
if you see this please open an issue on github https://github.com/home-assistant/android/issues/new/choose
Copy link
Member

Choose a reason for hiding this comment

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

Using similar text to core requesting filing a bug report, full sentences, shorter link.

Suggested change
The exception is ignored to avoid a crash but it should be handled
if you see this please open an issue on github https://github.com/home-assistant/android/issues/new/choose
The error has been ignored to avoid a crash, but it should be handled.
Please create a bug report at https://github.com/home-assistant/android/issues/new.

additionalMessage?.let {
appendLine()
appendLine(it)
appendLine(SEPARATOR)
Copy link
Member

Choose a reason for hiding this comment

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

Why add another line at the end only if there is an additional message?


class FailFastTest {

@Test
Copy link
Member

Choose a reason for hiding this comment

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

May I suggest another test for the fallback value?

authenticationRepository(it.id).getSessionState() == SessionState.CONNECTED
FailFast.failOnCatch(
message = {
"""Fail to get authenticationRepository for ${it.id} current authenticationRepos ids: ${authenticationRepos.keys} """
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"""Fail to get authenticationRepository for ${it.id} current authenticationRepos ids: ${authenticationRepos.keys} """
"""Failed to get authenticationRepository for ${it.id}. Current repository ids: ${authenticationRepos.keys}."""

FailFast.failOnCatch {
// Sometimes the service cannot be started as foreground due to the app being in a state where
// this is not allowed. We didn't identified yet how to avoid starting the service in this state.
// To avoid a crash, we catch it with FailFast, which will only crash in debug builds.
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this line obvious, so unnecessary?

LAUNCHER.onServiceCreated(this, notificationId, notification, type)
FailFast.failOnCatch {
// Sometimes the service cannot be started as foreground due to the app being in a state where
// this is not allowed. We didn't identified yet how to avoid starting the service in this state.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// this is not allowed. We didn't identified yet how to avoid starting the service in this state.
// this is not allowed. We haven't identified how to avoid starting the service in this state yet.

@jpelgrom jpelgrom changed the title Introcude FailFast utils to provide offensive programing Introduce FailFast utils to provide offensive programing May 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants