什么是捕捉“;响应太大而不能返回错误“;用于PHP的Google BigQuery API


What is the proper way to capture a "Response too large to return error" in Google BigQuery API for PHP?

在Google BigQuery web界面中,如果我运行的查询返回的响应太大,我会收到消息:

错误:响应太大,无法返回。请考虑在作业配置中将allowLargeResults设置为true。

当运行作业配置中未设置allowLargeResults的查询时,如何在Google BigQuery API界面中捕获此错误消息?

在各自的BigQuery API-作业中:获取此信息处于状态。errorResult
分别在
reason属性:responseToLarge
message属性:响应太大,无法返回。请考虑在作业配置中将allowLargeResults设置为true。有关更多详细信息

您还可以检查status.errors以获取作业执行过程中遇到的所有错误的更多详细信息

我们使用这个片段来处理错误,它起到了帮助作用:

当我们放置作业时,以及稍后在循环中检查作业的状态时,我们也有,因为当作业完成时,会弹出错误。

try {
                try {
                    $job = $bq->jobs->insert(PROJECT_ID, $job);
                } catch (Google_IO_Exception $e) {
                    $this->e('Exception: ' . $e->getMessage(), 'red');
                    $this->e('Strace: ' . $e->getTraceAsString());
                    if ($e->getMessage() == 'SSL connect error') {
                        $this->clearTokenFile();
                        $this->releaseJob();
                    }
                    return false;
                }
                $status = new Google_Service_Bigquery_JobStatus();
                $status = $job->getStatus();
                if (0 != $status->count()) {
                    $err_res = $status->getErrorResult();
                    $this->e($err_res->getMessage(), 'red');
                    return false;
                }
            } catch (Google_Service_Exception $e) {
                $this->e('Exception: ' . $e->getMessage(), 'red');
                return false;
            }

on和insert我们所拥有的,请注意reason字段:

try {
            $resp = new Google_Service_Bigquery_TableDataInsertAllResponse();
            $resp = $bq->tabledata->insertAll($project_id, $dataset_id, static::tableId(), $request);
            $errors = new Google_Service_Bigquery_TableDataInsertAllResponseInsertErrors();
            $errors = @$resp->getInsertErrors();
            if (!empty($errors)) {
                $error_msg = "'r'nRequest Headers: 'r'n" . json_encode($client->request->getRequestHeaders()) . "'r'nResponse Headers: 'r'n" . json_encode($client->request->getResponseHeaders()) . "'r'nRequest Body:'r'n" . $client->request->getPostBody() . "'r'nResponse Body:'r'n" . $client->request->getResponseBody() . "'r'n";
                if (is_array($errors)) {
                    foreach ($errors as $eP) {
                        $arr = $eP->getErrors();
                        $line = $eP->getIndex();
                        if (is_array($arr)) {
                            foreach ($arr as $e) {
                                switch ($e->getReason()) {
                                    case "stopped":
                                        break;
                                    case "timeout":
                                        $failed_lines[] = $line;
                                        $last_reason = $e->getReason();
                                        $error_msg.= sprintf("Timeout on line %s, reason: %s, msg: %s'r'n", $line, $e->getReason(), $e->getMessage());
                                        break;
                                    default:
                                        $error_msg.= sprintf("Error on line %s, reason: %s, msg: %s'r'n", $line, $e->getReason(), $e->getMessage());
                                        break;
                                }
                            }
                        } else {
                            $error_msg.= json_encode($arr) . "'r'n";
                        }
                    }
                    $this->setErrorMessage($error_msg);
                } else {
                    $this->setErrorMessage($errors);
                }
                //print_r($errors);
                //exit;
                $success = false;
            }
            return $ret;
        } catch (Google_Service_Exception $e) {
            $this->setErrors($e->getErrors())->setErrorMessage($e->getMessage());
            throw $e;
        }

回答我自己的问题:以下是我解决问题的摘要。总之,我无法让它为同步查询抛出错误,但可以让它为异步查询抛出错误。

以下是一个响应太大而无法返回的示例查询:

$query = "SELECT * FROM [publicdata:samples.github_timeline] LIMIT 1000000;"

同步查询

使用jobs.query:运行同步查询

try {
  $query_request = new Google_Service_Bigquery_QueryRequest();
  $query_request->setQuery($query);
  $res = $this->gbq_service->jobs->query($this->_project_id, $query_request);
  return $res;
} catch (Exception $e){
  echo $e->getMessage());
}

我收到的回复是:

{
  "cacheHit": null,
  "jobComplete": false,
  "kind": "bigquery#queryResponse",
  "pageToken": null,
  "totalBytesProcessed": null,
  "totalRows": null
}

所以在这种情况下,我仍然没有收到想要的"响应太大而无法返回"。

异步查询

如果我将作业作为异步查询运行,那么作业状态最终会设置为DONE,在检查结果时,会抛出一个错误,并显示消息:

{
  "error": "Error calling GET https://www.googleapis.com/bigquery/v2/projects/.../queries/job_2VICoK6yX0YMM_zRkJ10hT9mom8?timeoutMs=1000000&maxResults=100: (403) Response too large to return. Consider setting allowLargeResults to true in your job configuration. For more information, see https://cloud.google.com/bigquery/troubleshooting-errors",
}

告诉我需要将结果保存为表,并将allowLargeResults设置为true。

因此,简单的答案是将查询作为异步查询运行。

更新

我联系了谷歌,他们提到这可能是phpapi中的一个错误。他们已经表示,他们将把它转发给php-gbqneneneba API人员。