-
Notifications
You must be signed in to change notification settings - Fork 14.6k
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
Fix AWS RDS hook's DB instance state check #34773
Fix AWS RDS hook's DB instance state check #34773
Conversation
@@ -240,7 +240,7 @@ def get_db_instance_state(self, db_instance_id: str) -> str: | |||
try: | |||
response = self.conn.describe_db_instances(DBInstanceIdentifier=db_instance_id) | |||
except self.conn.exceptions.ClientError as e: | |||
if e.response["Error"]["Code"] == "DBInstanceNotFoundFault": | |||
if e.response["Error"]["Code"] == "DBInstanceNotFound": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AetherUnbound Thanks for creating the PR :)
Are there any version changes for SDK/Client/API used now vs earlier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to catch RDS.Client.exceptions.DBInstanceNotFoundFault (as self.conn.exceptions.DBInstanceNotFoundFault
) rather than generic ClientError and parse it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But service exceptions are wrapped into ClientError
. See documentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this is weird because from documentation it is DBInstanceNotFoundFault
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vincbeck Right, I mention this in the PR description - the error code itself within the ClientError
is DBInstanceNotFound
, but the exception is DBInstanceNotFoundFault
. I'm all for catching a more specific exception, but the other functions in this file will probably need to be updated as well and I wanted to confirm that was the right way forward before making that change 🙂
Are there any version changes for SDK/Client/API used now vs earlier?
Not that I'm aware of, I think this has been an issue since we started using this DAG! Let me take a look at our logs and get back to you though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But boto3 documentation is different from AWS API reference documentation:
- Boto3 documentation:
DBInstanceNotFoundFault
- API reference documentation:
DBInstanceNotFound
I trust your testing then and DBInstanceNotFound
should be the good one 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Response Error Code != Exception name
Some simple snippet for play with debugger
import boto3
from botocore.exceptions import ClientError
session = boto3.session.Session(...) # do not forget add creds/profile or set appropriate ENV Vars
client = session.client("rds")
try:
client.describe_db_instances(DBInstanceIdentifier="foo-bar-spam-egg")
except client.exceptions.DBInstanceNotFoundFault as ex:
assert isinstance(ex, ClientError)
assert isinstance(ex, client.exceptions.ClientError)
raise
If y'all are up for it, I can also change the other |
Would be great if you can do it as part of this PR. I'd double check this the correct error code though |
@@ -240,7 +240,7 @@ def get_db_instance_state(self, db_instance_id: str) -> str: | |||
try: | |||
response = self.conn.describe_db_instances(DBInstanceIdentifier=db_instance_id) | |||
except self.conn.exceptions.ClientError as e: | |||
if e.response["Error"]["Code"] == "DBInstanceNotFoundFault": | |||
if e.response["Error"]["Code"] == "DBInstanceNotFound": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we need to check both values since no one reported the issues before.
if e.response["Error"]["Code"] == "DBInstanceNotFound": | |
if e.response["Error"]["Code"] in ["DBInstanceNotFoundFault", "DBInstanceNotFound"]: |
However if @Taragolis solution is applicable, it would be much better.
I haven't forgotten about this, just got busy! It sounds like folks are comfortable with catching specific exceptions instead of checking error codes, which should be more robust in general. I'll modify this PR for all of the RDS functions to make it consistent in that regard. |
Interesting note, all of the exception types end in
Going to go ahead and change all the logic over! |
Crap, GitHub outage is affecting the build steps 😅 Anyone mind re-running them when you have a moment? |
I just rebased it. It will re-execute the tests. Though, I am not sure the outage is over |
Weird, it looks like a few tests are failing because they're raising a
|
Yes, this is expected from the documentation:
|
That's so odd, especially since local testing (shown in the issue description) raises a specific error in some cases 😅 Ah well, I'll change those pieces back. |
Hmm, that docs build failure seems unrelated 🤔 |
e4ae104
to
5b0daec
Compare
Yep. Rebased after: a) we fixed it in main |
Thanks for the work @AetherUnbound 🥳 |
Problem
We observed that when the
RdsDbSensor
is run against a database identifier which doesn't yet exist, the sensor fails and enters a retry sequence rather than emittingFalse
and poking again at the next interval: WordPress/openverse#2961The docs for
get_db_instance_state
say that this should raiseAirflowNotFoundException
if the DB instance doesn't exist, and theRdsDbSensor
'spoke
method would seem to comport this with how it's expecting to handle anAirflowNotFoundException
.However, when running the hook code locally, the hook instead raises a
DBInstanceNotFoundFault
exception:I tried extracting the error code that is checked here myself:
airflow/airflow/providers/amazon/aws/hooks/rds.py
Lines 229 to 246 in 0c8e30e
It looks like the code that should be checked against is actually
DBInstanceNotFound
, even if the exception isDBInstanceNotFoundFault
. I've made the change here, there are a few other places in this hook whereDB[issue]Fault
is used where perhapsDB[issue]
should be used instead. But I wanted to get this PR up with a minimal change at least to get folks' thoughts 🙂^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named
{pr_number}.significant.rst
or{issue_number}.significant.rst
, in newsfragments.