-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Improve dag error handling #49164
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
base: main
Are you sure you want to change the base?
Improve dag error handling #49164
Conversation
Congratulations on your first Pull Request and welcome to the Apache Airflow community! If you have any issues or are unsure about any anything please check our Contributors' Guide (https://github.com/apache/airflow/blob/main/contributing-docs/README.rst)
|
49162b4
to
49f4b74
Compare
airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py
Outdated
Show resolved
Hide resolved
airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_error_handling.py
Outdated
Show resolved
Hide resolved
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.
Thanks for the PR!
I agree with @rawwar, and also leave nits for modularizing.
airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py
Outdated
Show resolved
Hide resolved
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.
Thanks for the PR. A few adjustments needed before we can merge :)
airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py
Outdated
Show resolved
Hide resolved
airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py
Outdated
Show resolved
Hide resolved
airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py
Outdated
Show resolved
Hide resolved
airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py
Outdated
Show resolved
Hide resolved
airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py
Outdated
Show resolved
Hide resolved
49f4b74
to
e296a5d
Compare
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.
The main problem of this is it will really handle only a precise deserialization errror => dag_id is missing from the encoded dag.
Any other undexpected error in the deserialization process, will just crash and not provide any specific feedback.
I think we shoul catch everything in SerializedDAG.deserialize_dag
and raise based on the exception a new custom DeserializationError
.
Then all those deserialization errors can be catch on the API side and provide a relevant feedback.
airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py
Outdated
Show resolved
Hide resolved
airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_assets.py
Outdated
Show resolved
Hide resolved
Don't hesitate to directly |
e296a5d
to
a62f542
Compare
df76944
to
f1e2875
Compare
Hi @pierrejeambrun, |
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.
Nice, looking good. A few comments. Thanks.
airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py
Outdated
Show resolved
Hide resolved
airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py
Outdated
Show resolved
Hide resolved
airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_assets.py
Outdated
Show resolved
Hide resolved
c933083
to
73dad08
Compare
Hi @pierrejeambrun, |
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.
Overall looks good, thanks! Small comments here and there :)
airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py
Outdated
Show resolved
Hide resolved
airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dags.py
Outdated
Show resolved
Hide resolved
airflow-core/src/airflow/api_fastapi/core_api/routes/ui/assets.py
Outdated
Show resolved
Hide resolved
airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py
Outdated
Show resolved
Hide resolved
73dad08
to
a66859d
Compare
DatabaseErrorHandlers = [ | ||
_UniqueConstraintErrorHandler(), | ||
] | ||
|
||
DAGErrorHandlers = [ | ||
DAGErrorHandler(), | ||
] |
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.
Do we really need these to be separate? How about just have one list called ERROR_HANDLERS
instead.
Or, do we really need the list at all? Why not just import the classes directly in app.py
?
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.
+1 unique list of ErrorHandlers
seems more appropriate for now as there is really just one db handler.
|
||
return dag | ||
return dag | ||
except (RuntimeError, ValueError, KeyError) as err: |
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.
Does RuntimeError here only intend to catch the case we raise ourselves? I’d rather avoid it if possible; it’s used too often for built-in errors that we may not want to mask.
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 don't know, basically any unexpected error there is a deserialization error, and we prefer to wrap that into a DeserializationError (with the original stack trace), to show that to the users of the API, instead of having a plain ValueError/KeyError
with a 500 (Default ValueError and KeyError cannot be handled globally by the api server exception handler).
Raising anything else not handled by the server will end up in 500
and the error buried in the stack trace.
except: | ||
raise |
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.
except: | |
raise |
def exception_handler(self, request: Request, exc: DeserializationError): | ||
"""Handle DAG deserialization exceptions.""" | ||
raise HTTPException( | ||
status_code=status.HTTP_400_BAD_REQUEST, |
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.
400 does not sound right to me. This is not something the client can resolve; a 500 would be more appropriate IMO.
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.
+1. 400 'could work' maybe if we consider that a dag authorizing mistake causing the deserialization error and the user needs to operate on a the dag itself ?
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.
@pierrejeambrun Just to confirm, should we still raise a 400 status code in this case?
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.
lets try with a 500
as TP suggested.
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 feel Airflow should catch authoring mistakes and prevent un-deserialisable content enter the database; in that sense 500 is more appropriate. 400 still does not feel appropriate even if the input is fixable since the code implies the user can get a successful result simply by tweaking the request parameters.
Improve error handling for DAG access in API endpoints
This PR improves error handling when accessing DAGs via API endpoints:
This change ensures users get clear feedback when DAGs fail to load
due to import errors, syntax errors, or other unexpected issues.
closes: #48960
^ 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 airflow-core/newsfragments.