# Buggy code
def housekeeping():
    expired_threshold = request.args.get(
        "expired", current_app.config["DEFAULT_EXPIRED_DELETE_HRS"], type="int"
    )
    info_threshold = request.args.get(
        "info", current_app.config["DEFAULT_INFO_DELETE_HRS"], type="int"
    )

    has_expired, has_timedout = Alert.housekeeping(expired_threshold, info_threshold)

    errors = []
    for alert in has_expired:
        try:
            alert, _, text, timeout = process_action(
                alert,
                action="expired",
                text="",
                timeout=current_app.config["ALERT_TIMEOUT"],
            )
            alert = alert.from_expired(text, timeout)
        except RejectException as e:
            write_audit_trail.send(
                current_app._get_current_object(),
                event="alert-expire-rejected",
                message=alert.text,
                user=g.login,
                customers=g.customers,
                scopes=g.scopes,
                resource_id=alert.id,
                type="alert",
                request=request,
            )
            errors.append(str(e))
            continue
        except Exception as e:
            raise ApiError(str(e), 500)

        write_audit_trail.send(
            current_app._get_current_object(),
            event="alert-expired",
            message=text,
            user=g.login,
            customers=g.customers,
            scopes=g.scopes,
            resource_id=alert.id,
            type="alert",
            request=request,
        )

    for alert in has_timedout:
        try:
            alert, _, text, timeout = process_action(
                alert,
                action="timeout",
                text="",
                timeout=current_app.config["ALERT_TIMEOUT"],
            )
            alert = alert.from_timeout(text, timeout)
        except RejectException as e:
            write_audit_trail.send(
                current_app._get_current_object(),
                event="alert-timeout-rejected",
                message=alert.text,
                user=g.login,
                customers=g.customers,
                scopes=g.scopes,
                resource_id=alert.id,
                type="alert",
                request=request,
            )
            errors.append(str(e))
            continue
        except Exception as e:
            raise ApiError(str(e), 500)

        write_audit_trail.send(
            current_app._get_current_object(),
            event="alert-timeout",
            message=text,
            user=g.login,
            customers=g.customers,
            scopes=g.scopes,
            resource_id=alert.id,
            type="alert",
            request=request,
        )

    if errors:
        raise ApiError("housekeeping failed", 500, errors=errors)
    else:
        return jsonify(
            status="ok",
            expired=[a.id for a in has_expired],
            timedout=[a.id for a in has_timedout],
            count=len(has_expired) + len(has_timedout),
        )


# Traceback (nTypeError)
$ /opt/alerta/bin/alerta housekeeping --expired 72 --info 72
Error: {"code":500,"errors":["Traceback (most recent call last):\n  File \"/opt/alerta/lib64/python3.6/site-packages/flask/app.py\", line 1950, in full_dispatch_request\n    rv = self.dispatch_request()\n  File \"/opt/alerta/lib64/python3.6/site-packages/flask/app.py\", line 1936, in dispatch_request\n    return self.view_functions[rule.endpoint](**req.view_args)\n  File \"/opt/alerta/lib64/python3.6/site-packages/flask_cors/decorator.py\", line 128, in wrapped_function\n    resp = make_response(f(*args, **kwargs))\n  File \"/opt/alerta/lib64/python3.6/site-packages/alerta/auth/decorators.py\", line 53, in wrapped\n    return f(*args, **kwargs)\n  File \"/opt/alerta/lib64/python3.6/site-packages/alerta/management/views.py\", line 148, in housekeeping\n    expired_threshold = request.args.get('expired', current_app.config['DEFAULT_EXPIRED_DELETE_HRS'], type='int')\n  File \"/opt/alerta/lib64/python3.6/site-packages/werkzeug/datastructures.py\", line 319, in get\n    rv = type(rv)\nTypeError: 'str' object is not callable\n"],"message":"'str' object is not callable","requestId":"1b4b77c0-cb58-4b9d-a064-e0c548d0cbc3","status":"error"}

# Fixed code
def housekeeping():
    expired_threshold = request.args.get(
        "expired", default=current_app.config["DEFAULT_EXPIRED_DELETE_HRS"], type=int
    )
    info_threshold = request.args.get(
        "info", default=current_app.config["DEFAULT_INFO_DELETE_HRS"], type=int
    )

    has_expired, has_timedout = Alert.housekeeping(expired_threshold, info_threshold)

    errors = []
    for alert in has_expired:
        try:
            alert, _, text, timeout = process_action(
                alert,
                action="expired",
                text="",
                timeout=current_app.config["ALERT_TIMEOUT"],
            )
            alert = alert.from_expired(text, timeout)
        except RejectException as e:
            write_audit_trail.send(
                current_app._get_current_object(),
                event="alert-expire-rejected",
                message=alert.text,
                user=g.login,
                customers=g.customers,
                scopes=g.scopes,
                resource_id=alert.id,
                type="alert",
                request=request,
            )
            errors.append(str(e))
            continue
        except Exception as e:
            raise ApiError(str(e), 500)

        write_audit_trail.send(
            current_app._get_current_object(),
            event="alert-expired",
            message=text,
            user=g.login,
            customers=g.customers,
            scopes=g.scopes,
            resource_id=alert.id,
            type="alert",
            request=request,
        )

    for alert in has_timedout:
        try:
            alert, _, text, timeout = process_action(
                alert,
                action="timeout",
                text="",
                timeout=current_app.config["ALERT_TIMEOUT"],
            )
            alert = alert.from_timeout(text, timeout)
        except RejectException as e:
            write_audit_trail.send(
                current_app._get_current_object(),
                event="alert-timeout-rejected",
                message=alert.text,
                user=g.login,
                customers=g.customers,
                scopes=g.scopes,
                resource_id=alert.id,
                type="alert",
                request=request,
            )
            errors.append(str(e))
            continue
        except Exception as e:
            raise ApiError(str(e), 500)

        write_audit_trail.send(
            current_app._get_current_object(),
            event="alert-timeout",
            message=text,
            user=g.login,
            customers=g.customers,
            scopes=g.scopes,
            resource_id=alert.id,
            type="alert",
            request=request,
        )

    if errors:
        raise ApiError("housekeeping failed", 500, errors=errors)
    else:
        return jsonify(
            status="ok",
            expired=[a.id for a in has_expired],
            timedout=[a.id for a in has_timedout],
            count=len(has_expired) + len(has_timedout),
        )