summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-06-11 14:31:57 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2020-06-11 14:31:57 -0400
commitdbaf82d258cc12d92ef28de4677d147fdb7808fd (patch)
treee4239cbf2d6c9265ab28a2db1fb5844b114e3e49
parented4a4896aea7dd77dd5d8a9861302811ac421e47 (diff)
downloadsqlalchemy-dbaf82d258cc12d92ef28de4677d147fdb7808fd.tar.gz
Add version token to error URL
the sqlalche.me redirector now supports the numerical version code in the URL, e.g. /13/, /14/, /20/, etc., so that we can redirect to the error codes for the appropriate version of SQLAlchemy in use without going through the catch-all "latest" link. If a particular version of the docs is no longer on the site, the redirect will revert to falling through the "latest" link (which ultimately lands on the current release version, /13/ at the time of this writing). Change-Id: I3bb463fd6fb6c8767c95a57f3699aba715a9a72d
-rw-r--r--lib/sqlalchemy/__init__.py4
-rw-r--r--lib/sqlalchemy/exc.py4
-rw-r--r--test/base/test_except.py37
3 files changed, 35 insertions, 10 deletions
diff --git a/lib/sqlalchemy/__init__.py b/lib/sqlalchemy/__init__.py
index 27e9fd1c0..d52393d0b 100644
--- a/lib/sqlalchemy/__init__.py
+++ b/lib/sqlalchemy/__init__.py
@@ -142,5 +142,9 @@ def __go(lcls):
_sa_util.preloaded.import_prefix("sqlalchemy")
+ from . import exc
+
+ exc._version_token = "".join(__version__.split(".")[0:2])
+
__go(locals())
diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py
index 92322fb90..491dde7b2 100644
--- a/lib/sqlalchemy/exc.py
+++ b/lib/sqlalchemy/exc.py
@@ -15,6 +15,8 @@ raised as a result of DBAPI exceptions are all subclasses of
from .util import compat
+_version_token = None
+
class SQLAlchemyError(Exception):
"""Generic error class."""
@@ -33,7 +35,7 @@ class SQLAlchemyError(Exception):
else:
return (
"(Background on this error at: "
- "http://sqlalche.me/e/%s)" % (self.code,)
+ "http://sqlalche.me/e/%s/%s)" % (_version_token, self.code,)
)
def _message(self, as_unicode=compat.py3k):
diff --git a/test/base/test_except.py b/test/base/test_except.py
index be8c85a64..7ef077659 100644
--- a/test/base/test_except.py
+++ b/test/base/test_except.py
@@ -47,6 +47,17 @@ class SpecificIntegrityError(WrongNameError):
class WrapTest(fixtures.TestBase):
+ def test_version_token(self):
+ assert sa_exceptions._version_token in (
+ "13",
+ "14",
+ "15",
+ "16",
+ "20",
+ "21",
+ "22",
+ )
+
def _translating_dialect_fixture(self):
d = default.DefaultDialect()
d.dbapi_exception_translation_map = {
@@ -72,7 +83,8 @@ class WrapTest(fixtures.TestBase):
str(exc),
"(test.base.test_except.OperationalError) \n"
"[SQL: this is a message]\n"
- "(Background on this error at: http://sqlalche.me/e/e3q8)",
+ "(Background on this error at: http://sqlalche.me/e/%s/e3q8)"
+ % sa_exceptions._version_token,
)
def test_tostring_with_newlines(self):
@@ -89,7 +101,8 @@ class WrapTest(fixtures.TestBase):
"(test.base.test_except.OperationalError) \n"
"[SQL: this is a message\nthis is the next line\n"
"the last line]\n"
- "(Background on this error at: http://sqlalche.me/e/e3q8)",
+ "(Background on this error at: http://sqlalche.me/e/%s/e3q8)"
+ % sa_exceptions._version_token,
)
def test_statement_error_no_code(self):
@@ -122,7 +135,8 @@ class WrapTest(fixtures.TestBase):
"(sqlalchemy.exc.InvalidRequestError) hello\n"
"[SQL: select * from table]\n"
"[parameters: [{'x': 1}]]\n"
- "(Background on this error at: http://sqlalche.me/e/abcd)",
+ "(Background on this error at: http://sqlalche.me/e/%s/abcd)"
+ % sa_exceptions._version_token,
)
eq_(err.args, ("(sqlalchemy.exc.InvalidRequestError) hello",))
@@ -133,7 +147,8 @@ class WrapTest(fixtures.TestBase):
eq_(
str(orig),
"(2006, 'Test raise operational error')\n"
- "(Background on this error at: http://sqlalche.me/e/dbapi)",
+ "(Background on this error at: http://sqlalche.me/e/%s/dbapi)"
+ % sa_exceptions._version_token,
)
def test_wrap_unicode_arg(self):
@@ -144,7 +159,7 @@ class WrapTest(fixtures.TestBase):
compat.text_type(orig),
compat.u(
"méil\n(Background on this error at: "
- "http://sqlalche.me/e/dbapi)"
+ "http://sqlalche.me/e/%s/dbapi)" % sa_exceptions._version_token
),
)
eq_(orig.args, (u("méil"),))
@@ -217,7 +232,8 @@ class WrapTest(fixtures.TestBase):
"[SQL: this is a message]\n"
"[parameters: [{1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1},"
" {1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}]]\n"
- "(Background on this error at: http://sqlalche.me/e/e3q8)",
+ "(Background on this error at: http://sqlalche.me/e/%s/e3q8)"
+ % sa_exceptions._version_token,
)
eq_(
exc.args,
@@ -252,7 +268,8 @@ class WrapTest(fixtures.TestBase):
"{1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}, "
"{1: 1}, {1: 1} ... displaying 10 of 11 total "
"bound parameter sets ... {1: 1}, {1: 1}]]\n"
- "(Background on this error at: http://sqlalche.me/e/e3q8)",
+ "(Background on this error at: http://sqlalche.me/e/%s/e3q8)"
+ % sa_exceptions._version_token,
)
try:
raise sa_exceptions.DBAPIError.instance(
@@ -269,7 +286,8 @@ class WrapTest(fixtures.TestBase):
"[SQL: this is a message]\n"
"[parameters: [(1,), "
"(1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,)]]\n"
- "(Background on this error at: http://sqlalche.me/e/e3q8)",
+ "(Background on this error at: http://sqlalche.me/e/%s/e3q8)"
+ % sa_exceptions._version_token,
)
try:
raise sa_exceptions.DBAPIError.instance(
@@ -300,7 +318,8 @@ class WrapTest(fixtures.TestBase):
"(1,), (1,), (1,), (1,), (1,), (1,), (1,) "
"... displaying 10 of 11 total bound "
"parameter sets ... (1,), (1,)]]\n"
- "(Background on this error at: http://sqlalche.me/e/e3q8)",
+ "(Background on this error at: http://sqlalche.me/e/%s/e3q8)"
+ % sa_exceptions._version_token,
)
def test_db_error_busted_dbapi(self):