Airflow: task marked as failed when sys.exit(0)

Created on 2 Oct 2020  路  6Comments  路  Source: apache/airflow

Apache Airflow version:
apache-airflow (1.10.10)

Environment:
Docker version 19.03.12

  • OS (e.g. from /etc/os-release):
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
  • Kernel (e.g. uname -a):

4.19.76-linuxkit

What happened:

I'm testing this small DAG (see below) consisting of a simple task using PythonOperator. I'd like to exit the call with a exit code 0 when everything went fine, however airflow seems to be marking the task as failed when this happen.
The log file:


[2020-10-02 09:44:13,081] {taskinstance.py:669} INFO - Dependencies all met for <TaskInstance: TEST_0.test_task 2020-10-02T09:43:00+00:00 [queued]>
[2020-10-02 09:44:13,735] {taskinstance.py:669} INFO - Dependencies all met for <TaskInstance: TEST_0.test_task 2020-10-02T09:43:00+00:00 [queued]>
[2020-10-02 09:44:13,736] {taskinstance.py:879} INFO - 
--------------------------------------------------------------------------------
[2020-10-02 09:44:13,737] {taskinstance.py:880} INFO - Starting attempt 1 of 1
[2020-10-02 09:44:13,737] {taskinstance.py:881} INFO - 
--------------------------------------------------------------------------------
[2020-10-02 09:44:14,288] {taskinstance.py:900} INFO - Executing <Task(PythonOperator): test_task> on 2020-10-02T09:43:00+00:00
[2020-10-02 09:44:14,291] {standard_task_runner.py:53} INFO - Started process 10800 to run task
[2020-10-02 09:44:16,389] {logging_mixin.py:112} INFO - Running %s on host %s <TaskInstance: TEST_0.test_task 2020-10-02T09:43:00+00:00 [running]> 3a160363119b
[2020-10-02 09:44:17,433] {logging_mixin.py:112} INFO - doing stuff inside task
[2020-10-02 09:44:22,195] {logging_mixin.py:112} INFO - [2020-10-02 09:44:22,195] {local_task_job.py:103} INFO - Task exited with return code 0

What you expected to happen:
I'm expecting the task marked as succed, or at least understand why airflow marks this task as failed despite of the exit code 0.

How to reproduce it:
Here is the code

import sys
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from airflow.utils.dates import days_ago

default_args = {
    'depends_on_past': False,
    'start_date': days_ago(1),
    'retries': 0,
}

DAG_NAME = 'TEST_0'
SCH_INTERVAL = '0/1 * * * *'

def task():
    print('doing stuff inside task')
    sys.exit(0)

with DAG(
    DAG_NAME,
    default_args=default_args,
    schedule_interval=SCH_INTERVAL,
    ) as dag:

    task_instance = PythonOperator( task_id='test_task', python_callable=task)

And the status in the UI:

image

thanks!

scheduleexecutor bug

Most helpful comment

@SergioShz Airflow performs a few more operations after the execution of the operator's execute method, e.g. marks a task in the database as completed or executes or executes callbacks. If this code is not executed the task will always be marked as abnormal completion = failed.

All 6 comments

Thanks for opening your first issue here! Be sure to follow the issue template!

You don't need to explicitly call sys.exit(0) -- as Airflow will do it under the hood if the commands succeded.

You can do the other way around, i.e. do a sys.exit(1) when one of the criteria you are checking it against fails

Hi, thanks for the quick answer!

Yes, that's what I'm currently doing as fix
but what I'm trying to point out is that if the command succeeds is the same as having a return code of 0 and that it's exactly what sys.exit(0) does explicitly, and in this case I don't see why the task should be marked as failed.

@SergioShz Airflow performs a few more operations after the execution of the operator's execute method, e.g. marks a task in the database as completed or executes or executes callbacks. If this code is not executed the task will always be marked as abnormal completion = failed.

If you change

def task():
    print('doing stuff inside task')
    sys.exit(0)

to:

def task():
    print('doing stuff inside task')
    return

wouldn't that solve the issue?

Hi, sorry for the late reply. I finally just avoided to use sys.exit(0). The answer of @mik-laj is what I needed just to understand a little bit more on why avoid to use this exit code.

I'm closing this, thanks all for your help!

Was this page helpful?
0 / 5 - 0 ratings