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 a more specific rescue to avoid hiding unexpected errors #21038

Merged
merged 1 commit into from
Feb 11, 2021

Conversation

Fryguy
Copy link
Member

@Fryguy Fryguy commented Feb 10, 2021

Follow up to #21037

If this code were in place prior to the Rails 6 upgrade, then we would have found the accidental override at that time.

To test, we can do the following:

$ bin/rake db:drop
$ bin/rails c # should not blow up

$ bin/rake db:create
$ bin/rails c
> Settings.log.level # => "info"

$ bin/rake db:migrate
$ bin/rails c
> Settings.log.level # => "info"

$ bin/rake db:seed
$ bin/rails c
> Settings.log.level # => "info"
> Vmdb::Settings.save!(MiqServer.my_server, :log => {:level => "debug"})
> Settings.reload!
> Settings.log.level # => "debug"

$ bin/rails c
> Settings.log.level # => "debug"

@NickLaMuro @agrare Please review.

@Fryguy Fryguy requested a review from gtanzillo as a code owner February 10, 2021 22:33
@Fryguy Fryguy force-pushed the more_specific_database_check branch from 424f3f6 to 02c67e3 Compare February 10, 2021 22:36
Copy link
Member

@NickLaMuro NickLaMuro left a comment

Choose a reason for hiding this comment

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

My one suggestion for an improvement.

conn && ActiveRecord::Base.connected?
ActiveRecord::Base.connection && ActiveRecord::Base.connected?
rescue ActiveRecord::NoDatabaseError
false
Copy link
Member

Choose a reason for hiding this comment

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

I think the other case we want to do is this (as I was working on the same thing 😉 ):

def database_connectivity?
  ActiveRecord::Base.connection && ActiveRecord::Base.connected?
rescue ActiveRecord::NoDatabaseError
  false
rescue => e
  return false if e.message =~ /^Could not load database configuration\./
end

From here:

https://github.com/rails/rails/blob/fe76a95b0d252a2d7c25e69498b720c96b243ea2/railties/lib/rails/application/configuration.rb#L241

(and there is no specified error... so you have to match on message...)

Copy link
Member Author

@Fryguy Fryguy Feb 10, 2021

Choose a reason for hiding this comment

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

Yeah, I can add that. Only problem is how to verify it? Did you run a specific rake task? (rake environment blows up otherwise) When I delete config/database.yml it blows up before it reaches this code.

Copy link
Member

Choose a reason for hiding this comment

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

@Fryguy I did a mv config/database.yml config/database.yml.bak and then tested it by just doing:

$ bin/rails r "foo = 1"

That said, the regexp could probably just change to:

/^(?:Could |Can)not load database configuration(?:\.|:)/

Which should cover both errors.

Copy link
Member

@NickLaMuro NickLaMuro Feb 10, 2021

Choose a reason for hiding this comment

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

@Fryguy Oh crap... in my code up above, I forgot to add another raise right after the return false, so it would re-raise if it doesn't catch the specific error.

My bad, it is what I had locally, but didn't put it here.

Full code then should be:

def database_connectivity?
  ActiveRecord::Base.connection && ActiveRecord::Base.connected?
rescue ActiveRecord::NoDatabaseError
  false
rescue => e
  return false if e.message =~ /^Could not load database configuration\./
  raise
end

Copy link
Member Author

Choose a reason for hiding this comment

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

But I can't even get to that point...it blows up before this code is even hit. In fact, the code doesn't even get to initializing the settings as it blows up way before this line, which is where the Settings are loaded first.

Vmdb::Settings.init

Copy link
Member

@NickLaMuro NickLaMuro Feb 10, 2021

Choose a reason for hiding this comment

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

Okay, so the other way I was tested was doing:

$ mv config/database.yml ...
$ bundle exec rake environment

That is how I got the "Could not load database configuration..." error instead.

Copy link
Member

Choose a reason for hiding this comment

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

Was also testing with

$ bundle exec rake test:verify_no_db_access_loading_rails_environment

Since the .with_dummy_database_url_configuration is used for stuff like building UI assets.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll give those a shot...thanks

Copy link
Member Author

@Fryguy Fryguy Feb 11, 2021

Choose a reason for hiding this comment

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

rake test:verify_no_db_access_loading_rails_environment passes with this PR as is (without your addition). rake environment fails with a missing config/database.yml, but not on the code in question (it fails much earlier).

I still can't exercise the code in question. For example, if instead I put

      rescue => err
        raise "XXX HI - #{err}"

I can't seem to find a way to get the XXX error.

Copy link
Member

Choose a reason for hiding this comment

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

So talking with @Fryguy in DMs, I think this is pretty hard to reach in this class, so adding the extra rescue is probably not necessary or a use case we can currently hit. That said, I also can't see it hurting anything either, since if code surrounding it would ever change to allow the lacking of a config/database.yml to be missing, then this wouldn't half execution (which seems like a valid use case for this class in particular).

That said, it isn't a hill I am willing to die on, so I am going to approve this PR, but leave this "unresolved" just so the comments for this are more prevalent for those looking back.

To test, we can do the following:

```
$ bin/rake db:drop
$ bin/rails c # should not blow up

$ bin/rake db:create
$ bin/rails c
> Settings.log.level # => "info"

$ bin/rake db:migrate
$ bin/rails c
> Settings.log.level # => "info"

$ bin/rake db:seed
$ bin/rails c
> Settings.log.level # => "info"
> Vmdb::Settings.save!(MiqServer.my_server, :log => {:level => "debug"})
> Settings.reload!
> Settings.log.level # => "debug"

$ bin/rails c
> Settings.log.level # => "debug"
```
@Fryguy Fryguy force-pushed the more_specific_database_check branch from 02c67e3 to 76731ae Compare February 10, 2021 23:24
@miq-bot
Copy link
Member

miq-bot commented Feb 10, 2021

Checked commit Fryguy@76731ae with ruby 2.6.3, rubocop 0.82.0, haml-lint 0.35.0, and yamllint
1 file checked, 0 offenses detected
Everything looks fine. 🏆

@Fryguy
Copy link
Member Author

Fryguy commented Feb 11, 2021

I think the Travis failure is a sporadic test failure and is unrelated. That spec passes locally. I'm doing some more tests locally the see if I can recreate.

@agrare agrare merged commit 03da03a into ManageIQ:master Feb 11, 2021
@Fryguy Fryguy deleted the more_specific_database_check branch February 11, 2021 20:50
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.

4 participants