Skip to content

Commit 2057c2e

Browse files
committed
feat!: Improves error handling.
In particular includes more information on GoogleApiException.Message when possible. Closes #8206 BREAKING CHANGE: If calling code depended on exact exception message.
1 parent 123f543 commit 2057c2e

4 files changed

Lines changed: 44 additions & 14 deletions

File tree

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2.IntegrationTests/InsertTest.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,30 @@ public void InsertRow_BadData_Throws(InsertOptions options, int[] errorRowsIndex
147147
}
148148
}
149149

150+
[Fact]
151+
public void InsertRow_Single_Throws()
152+
{
153+
var client = BigQueryClient.Create(_fixture.ProjectId);
154+
var dataset = client.GetDataset(_fixture.DatasetId);
155+
// Don't insert into a table used by other tests...
156+
var table = dataset.CreateTable(
157+
_fixture.CreateTableId(),
158+
new TableSchemaBuilder { { "year", BigQueryDbType.Int64 } }.Build());
159+
var row = new BigQueryInsertRow { { "noSuchField", 10 } };
160+
161+
var exception = Assert.Throws<GoogleApiException>(() => table.InsertRow(row));
162+
163+
Assert.Equal(
164+
"The service bigquery has thrown an exception. " +
165+
"No HttpStatusCode was specified. " +
166+
"Error inserting data: 1 error(s). " +
167+
"Status: NoRowsInserted. " +
168+
"First error message: Error in row 0. no such field: noSuchField.",
169+
exception.Message);
170+
Assert.Equal(1, exception.Error.Errors.Count);
171+
Assert.Contains(exception.Error.Errors, e => e.Message.ToLower().Contains($"in row 0"));
172+
}
173+
150174
public static IEnumerable<object[]> BadDataSilentOptions
151175
{
152176
get

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2/BigQueryInsertResults.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public BigQueryInsertResults(BigQueryClient client, InsertOptions options, IRead
9494
int originalRowsWithErrors = 0;
9595
_errors = errorsByRow
9696
.Select(rowErrors => new BigQueryInsertRowErrors(GetRow(rowErrors.Key), rowErrors.ToList().AsReadOnly()))
97+
.OrderBy(rowErrors => rowErrors.OriginalRowIndex ?? long.MaxValue)
9798
.ToList().AsReadOnly();
9899

99100
OriginalRowsWithErrors = originalRowsWithErrors;
@@ -125,7 +126,7 @@ public BigQueryInsertResults ThrowOnNoneInserted() =>
125126

126127
/// <summary>
127128
/// Throws <see cref="GoogleApiException"/> if there were insert errors.
128-
/// The excetpion will contain details of these errors.
129+
/// The exception will contain details of these errors.
129130
/// </summary>
130131
/// <exception cref="GoogleApiException">There were insert errors.</exception>
131132
public BigQueryInsertResults ThrowOnAnyError()
@@ -135,14 +136,17 @@ public BigQueryInsertResults ThrowOnAnyError()
135136
return this;
136137
}
137138

138-
var exception = new GoogleApiException(_client.Service.Name, $"Error inserting data. Status: {Status}")
139+
var flattenedErrors = Errors.SelectMany(rowErrors => rowErrors).ToList();
140+
throw new GoogleApiException(_client.Service.Name)
139141
{
140142
Error = new RequestError
141143
{
142-
Errors = Errors.SelectMany(rowErrors => rowErrors).ToList()
144+
Errors = flattenedErrors,
145+
Message = $"Error inserting data: {flattenedErrors.Count} error(s). " +
146+
$"Status: {Status}. " +
147+
$"First error message: { flattenedErrors.First().Message }"
143148
}
144149
};
145-
throw exception;
146150
}
147151

148152
internal BigQueryInsertResults ThrowIfNotSuppressing(bool? suppressInsertErrors) =>

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2/BigQueryJob.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,18 @@ public BigQueryJob ThrowOnAnyError()
107107
var errors = Resource.Status?.Errors;
108108
if (errors?.Count > 0)
109109
{
110-
throw new GoogleApiException(_client.Service.Name, $"Job {Reference?.ProjectId}/{Reference?.Location}/{Reference?.JobId} contained errors")
110+
throw new GoogleApiException(_client.Service.Name)
111111
{
112112
Error = new RequestError
113113
{
114114
Errors = errors.Select(error => new SingleError
115-
{
116-
Location = error.Location,
117-
Reason = error.Reason,
118-
Message = error.Message
119-
})
120-
.ToList()
115+
{
116+
Location = error.Location,
117+
Reason = error.Reason,
118+
Message = error.Message
119+
}).ToList(),
120+
Message = $"Job {Reference?.ProjectId}/{Reference?.Location}/{Reference?.JobId} contained {errors.Count} error(s). " +
121+
$"First error message: {errors.First().Message}"
121122
}
122123
};
123124
}

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2/BigQueryResults.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public BigQueryResults ThrowOnAnyError()
216216
var errors = _response.Errors;
217217
if (errors?.Count > 0)
218218
{
219-
throw new GoogleApiException(_client.Service.Name, $"Job {JobReference.ProjectId}/{JobReference.Location}/{JobReference.JobId} contained errors")
219+
throw new GoogleApiException(_client.Service.Name)
220220
{
221221
Error = new RequestError
222222
{
@@ -225,8 +225,9 @@ public BigQueryResults ThrowOnAnyError()
225225
Location = error.Location,
226226
Reason = error.Reason,
227227
Message = error.Message
228-
})
229-
.ToList()
228+
}).ToList(),
229+
Message = $"Job {JobReference.ProjectId}/{JobReference.Location}/{JobReference.JobId} contained {errors.Count} error(s). " +
230+
$"First error message: {errors.First().Message}"
230231
}
231232
};
232233
}

0 commit comments

Comments
 (0)