Currently if an API URL that does not exist is requested, an html page is returned instead of JSON

**Apache Airflow version**:2.0

**What happened**:
Making a request against an endpoint that does not exist returns an html page

**What you expected to happen**:

I expected it to return 404 error in JSON indicating that the URL was not found

**How to reproduce it**:
1. Start airflow website and scheduler in breeze.
2. Make a request against an endpoint that does not exist e.g http://localhost:28080/api/v1/getconnectiond
3. Notice that an html page is returned instead of a json
cc: @mik-laj 

airflow/www/extensions/init_views.py
)
    appbuilder.add_view(
        views.PoolModelView, permissions.RESOURCE_POOL, category=permissions.RESOURCE_ADMIN_MENU
    )
    appbuilder.add_view(
        views.XComModelView, permissions.RESOURCE_XCOM, category=permissions.RESOURCE_ADMIN_MENU
    )
    
    
    appbuilder.add_view_no_menu(views.RedocView)
def init_plugins(app):
    """Integrate Flask and FAB with plugins"""
    from airflow import plugins_manager
    plugins_manager.initialize_web_ui_plugins()
    appbuilder = app.appbuilder
    for view in plugins_manager.flask_appbuilder_views:
        log.debug("Adding view %s", view["name"])
        appbuilder.add_view(view["view"], view["name"], category=view["category"])
    for menu_link in sorted(plugins_manager.flask_appbuilder_menu_links, key=lambda x: x["name"]):
        log.debug("Adding menu link %s", menu_link["name"])
        appbuilder.add_link(
            menu_link["name"],
            href=menu_link["href"],
            category=menu_link["category"],
            category_icon=menu_link["category_icon"],
        )
    for blue_print in plugins_manager.flask_blueprints:
        log.debug("Adding blueprint %s:%s", blue_print["name"], blue_print["blueprint"].import_name)
        app.register_blueprint(blue_print["blueprint"])
def init_error_handlers(app: Flask):