This is an automated email from the ASF dual-hosted git repository.
rahulvats pushed a commit to branch v2-11-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v2-11-test by this push:
new 48a1af33384 Fixing 500 error on webserver after upgrading to FAB
provider 1.5.4 (#62412)
48a1af33384 is described below
commit 48a1af3338473da2a15d28efd0c14b6090f9204f
Author: Rahul Vats <[email protected]>
AuthorDate: Tue Feb 24 21:05:03 2026 +0530
Fixing 500 error on webserver after upgrading to FAB provider 1.5.4 (#62412)
---
airflow/www/session.py | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/airflow/www/session.py b/airflow/www/session.py
index 41cfbef8496..c85db73af15 100644
--- a/airflow/www/session.py
+++ b/airflow/www/session.py
@@ -16,6 +16,7 @@
# under the License.
from __future__ import annotations
+import logging
from typing import TYPE_CHECKING
from flask import request
@@ -24,7 +25,11 @@ from flask.sessions import SecureCookieSessionInterface
from flask_session.sqlalchemy import SqlAlchemySessionInterface
if TYPE_CHECKING:
+ from flask import Flask
from flask_session import Session
+ from werkzeug.wrappers import Request
+
+log = logging.getLogger(__name__)
class SessionExemptMixin:
@@ -39,6 +44,10 @@ class SessionExemptMixin:
return super().save_session(*args, **kwargs)
+class _SessionDeserializeError(Exception):
+ """Sentinel raised when session data cannot be deserialized."""
+
+
class AirflowTaggedJSONSerializer(TaggedJSONSerializer):
"""
Adapter of flask's serializer for flask-session.
@@ -56,7 +65,10 @@ class AirflowTaggedJSONSerializer(TaggedJSONSerializer):
def decode(self, data: bytes) -> Session:
"""Deserialize the session data."""
- return self.loads(data.decode())
+ try:
+ return self.loads(data.decode())
+ except Exception as e:
+ raise _SessionDeserializeError() from e
class AirflowDatabaseSessionInterface(SessionExemptMixin,
SqlAlchemySessionInterface):
@@ -66,6 +78,21 @@ class AirflowDatabaseSessionInterface(SessionExemptMixin,
SqlAlchemySessionInter
super().__init__(*args, **kwargs)
self.serializer = AirflowTaggedJSONSerializer()
+ def open_session(self, app: Flask, request: Request):
+ """
+ Open the session, starting a fresh one if the stored data cannot be
deserialized.
+
+ Session data serialized by an older flask-session version (<0.8.0)
+ cannot be read after an upgrade. Rather than letting the error
propagate and leave
+ ctx.session as None, we discard the unreadable session and issue a new
one.
+ """
+ try:
+ return super().open_session(app, request)
+ except _SessionDeserializeError:
+ log.warning("Failed to deserialize session data, starting a fresh
session.", exc_info=True)
+ sid = self._generate_sid(self.sid_length)
+ return self.session_class(sid=sid, permanent=self.permanent)
+
class AirflowSecureCookieSessionInterface(SessionExemptMixin,
SecureCookieSessionInterface):
"""Session interface that exempts some routes and stores session data in a
signed cookie."""