Java中如何遍历BigQuery返回的errors[]错误集合
BigQuery Java加载任务获取详细错误实现
问题复现
执行如下BigQuery Java SDK代码,从GCS加载JSON格式数据到BigQuery表时,在job.waitFor()行抛出异常:
注:代码中字符串参数均为模拟示例值
package bigquery.test; import java.io.FileInputStream; import java.io.InputStream; import com.google.auth.oauth2.GoogleCredentials; import com.google.cloud.bigquery.BigQuery; import com.google.cloud.bigquery.BigQueryOptions; import com.google.cloud.bigquery.Job; import com.google.cloud.bigquery.Table; import com.google.cloud.bigquery.TableId; public class GoogleBigQueryErrors { static BigQuery __bigquery__; public static void main(String[] args) { try { prepare(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } TableId tableId = com.google.cloud.bigquery.TableId.of("DATA_SET", "TABLE"); Table table = __bigquery__.getTable(tableId); Job job = table.load(com.google.cloud.bigquery.FormatOptions.json(), "gs://URI_PATH/HASH.bigquery.json"); Job completedJob = null; try { completedJob = job.waitFor(); // 错误在此处抛出 } catch (Exception e) { e.printStackTrace(); System.exit(2); } } private static void prepare() throws Exception { String projectId = "PROJECT_ID"; String credentialsFile = "PATH/FILE.json"; InputStream credentialsStream = new FileInputStream(credentialsFile); GoogleCredentials credentials = GoogleCredentials.fromStream(credentialsStream); BigQueryOptions options = BigQueryOptions.newBuilder().setProjectId(projectId).setCredentials(credentials) .build(); BigQuery bigquery = options.getService(); __bigquery__ = bigquery; } }
抛出的异常信息如下:
com.google.cloud.bigquery.BigQueryException: Error while reading data, error message: JSON table encountered too many errors, giving up. Rows: 1; errors: 1. Please look into the errors[] collection for more details.
查阅官方JavaDoc未找到直接获取errors集合的方法:
com.google.cloud.bigquery.Job类无getErrors或等效命名的方法- 存在
com.google.cloud.bigquery.BigQueryErrorMessages类,但无法从Job实例获取该类对象
实现方案
详细错误存放在任务状态的执行错误列表中,直接通过Job实例的状态对象即可获取,修改异常捕获部分代码如下:
// 提前导入需要的类 // import com.google.cloud.bigquery.BigQueryError; // import com.google.cloud.bigquery.JobStatistics; // import java.util.List; try { completedJob = job.waitFor(); // 无异常抛出时也需要校验任务状态,部分失败场景不会直接触发异常 if (completedJob != null && completedJob.getStatus().getError() != null) { System.out.println("任务顶层错误:" + completedJob.getStatus().getError()); } } catch (Exception e) { // waitFor抛出异常时,原job实例已同步服务端返回的最终任务状态,无需额外拉取 List<BigQueryError> executionErrors = job.getStatus().getExecutionErrors(); // 遍历打印所有具体错误,即提示中提到的errors[]集合内容 for (int i = 0; i < executionErrors.size(); i++) { BigQueryError err = executionErrors.get(i); System.out.printf("详细错误%d:错误码=%s,原因=%s,位置=%s,信息=%s%n", i + 1, err.getCode(), err.getReason(), err.getLocation(), err.getMessage() ); } // 可额外获取加载任务统计信息 JobStatistics.LoadStatistics loadStats = job.getStatistics(); System.out.printf("加载统计:坏记录数=%d,输入文件数=%d,写入成功记录数=%d%n", loadStats.getBadRecords(), loadStats.getInputFiles(), loadStats.getOutputRows() ); e.printStackTrace(); System.exit(2); }
关键说明
Job.getStatus().getError()返回的是任务顶层总错误,也就是当前看到的"too many errors, giving up"这类汇总提示Job.getStatus().getExecutionErrors()返回的列表就是提示中提到的errors[]集合,包含所有行级、字段级的具体解析错误,比如字段类型不匹配、缺失必填字段、JSON格式非法等具体信息- 调用
waitFor()方法时SDK会自动更新原Job实例的状态,即使抛出异常也不需要重新调用接口拉取Job信息 - 所有类型的BigQuery任务(查询、加载、导出、复制)的执行错误都可以通过
getExecutionErrors()方法获取,不是加载任务特有的逻辑
内容的提问来源于stack exchange,提问作者ymir
相关产品推荐
相关产品推荐

