Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite23114c

Browse files
authored
fix: remove query text from exception message, useexception.debug_message instead (#1105)
Since query text can potentially contain sensitive information, remove it fromthe default exception message. This information is useful for debugging, soprovide a `debug_message` attribute, which is not included in the exceptionrepresentation (and thus the logs).Fixes internal issue 211616590
1 parent18ee0b7 commite23114c

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

‎google/cloud/bigquery/job/query.py‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767

6868
_CONTAINS_ORDER_BY=re.compile(r"ORDER\s+BY",re.IGNORECASE)
69+
_EXCEPTION_FOOTER_TEMPLATE="{message}\n\nLocation: {location}\nJob ID: {job_id}\n"
6970
_TIMEOUT_BUFFER_SECS=0.1
7071

7172

@@ -1196,17 +1197,17 @@ def _blocking_poll(self, timeout=None, **kwargs):
11961197
super(QueryJob,self)._blocking_poll(timeout=timeout,**kwargs)
11971198

11981199
@staticmethod
1199-
def_format_for_exception(query,job_id):
1200+
def_format_for_exception(message:str,query:str):
12001201
"""Format a query for the output in exception message.
12011202
12021203
Args:
1204+
message (str): The original exception message.
12031205
query (str): The SQL query to format.
1204-
job_id (str): The ID of the job that ran the query.
12051206
12061207
Returns:
12071208
str: A formatted query text.
12081209
"""
1209-
template="\n\n(job ID: {job_id})\n\n{header}\n\n{ruler}\n{body}\n{ruler}"
1210+
template="{message}\n\n{header}\n\n{ruler}\n{body}\n{ruler}"
12101211

12111212
lines=query.splitlines()
12121213
max_line_len=max(len(line)forlineinlines)
@@ -1223,7 +1224,7 @@ def _format_for_exception(query, job_id):
12231224
"{:4}:{}".format(n,line)forn,lineinenumerate(lines,start=1)
12241225
)
12251226

1226-
returntemplate.format(job_id=job_id,header=header,ruler=ruler,body=body)
1227+
returntemplate.format(message=message,header=header,ruler=ruler,body=body)
12271228

12281229
def_begin(self,client=None,retry=DEFAULT_RETRY,timeout=None):
12291230
"""API call: begin the job via a POST request
@@ -1248,7 +1249,10 @@ def _begin(self, client=None, retry=DEFAULT_RETRY, timeout=None):
12481249
try:
12491250
super(QueryJob,self)._begin(client=client,retry=retry,timeout=timeout)
12501251
exceptexceptions.GoogleAPICallErrorasexc:
1251-
exc.message+=self._format_for_exception(self.query,self.job_id)
1252+
exc.message=_EXCEPTION_FOOTER_TEMPLATE.format(
1253+
message=exc.message,location=self.location,job_id=self.job_id
1254+
)
1255+
exc.debug_message=self._format_for_exception(exc.message,self.query)
12521256
exc.query_job=self
12531257
raise
12541258

@@ -1447,7 +1451,10 @@ def do_get_result():
14471451
do_get_result()
14481452

14491453
exceptexceptions.GoogleAPICallErrorasexc:
1450-
exc.message+=self._format_for_exception(self.query,self.job_id)
1454+
exc.message=_EXCEPTION_FOOTER_TEMPLATE.format(
1455+
message=exc.message,location=self.location,job_id=self.job_id
1456+
)
1457+
exc.debug_message=self._format_for_exception(exc.message,self.query)# type: ignore
14511458
exc.query_job=self# type: ignore
14521459
raise
14531460
exceptrequests.exceptions.Timeoutasexc:

‎tests/unit/job/test_query.py‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,13 +1360,19 @@ def test_result_error(self):
13601360
exc_job_instance=getattr(exc_info.exception,"query_job",None)
13611361
self.assertIs(exc_job_instance,job)
13621362

1363+
# Query text could contain sensitive information, so it must not be
1364+
# included in logs / exception representation.
13631365
full_text=str(exc_info.exception)
13641366
assertjob.job_idinfull_text
1365-
assert"Query Job SQL Follows"infull_text
1367+
assert"Query Job SQL Follows"notinfull_text
13661368

1369+
# It is useful to have query text available, so it is provided in a
1370+
# debug_message property.
1371+
debug_message=exc_info.exception.debug_message
1372+
assert"Query Job SQL Follows"indebug_message
13671373
fori,lineinenumerate(query.splitlines(),start=1):
13681374
expected_line="{}:{}".format(i,line)
1369-
assertexpected_lineinfull_text
1375+
assertexpected_lineindebug_message
13701376

13711377
deftest_result_transport_timeout_error(self):
13721378
query=textwrap.dedent(
@@ -1452,13 +1458,19 @@ def test__begin_error(self):
14521458
exc_job_instance=getattr(exc_info.exception,"query_job",None)
14531459
self.assertIs(exc_job_instance,job)
14541460

1461+
# Query text could contain sensitive information, so it must not be
1462+
# included in logs / exception representation.
14551463
full_text=str(exc_info.exception)
14561464
assertjob.job_idinfull_text
1457-
assert"Query Job SQL Follows"infull_text
1465+
assert"Query Job SQL Follows"notinfull_text
14581466

1467+
# It is useful to have query text available, so it is provided in a
1468+
# debug_message property.
1469+
debug_message=exc_info.exception.debug_message
1470+
assert"Query Job SQL Follows"indebug_message
14591471
fori,lineinenumerate(query.splitlines(),start=1):
14601472
expected_line="{}:{}".format(i,line)
1461-
assertexpected_lineinfull_text
1473+
assertexpected_lineindebug_message
14621474

14631475
deftest__begin_w_timeout(self):
14641476
PATH="/projects/%s/jobs"% (self.PROJECT,)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp