Skip to content

Commit edb839e

Browse files
authored
Minor error handling improvements (#8061)
* Throw more specific exceptions when the error is due to bad input (backport of cr/359824564) (note that this only applies to the Unity build); * Always log exceptions to make sure they make it into the log (regardless of exception handling by the user and any potential issues with the exception propagation mechanism). #no-changelog
1 parent 44ab89e commit edb839e

File tree

7 files changed

+30
-13
lines changed

7 files changed

+30
-13
lines changed

Firestore/Example/Tests/Integration/API/FIRValidationTests.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ - (void)testBatchWritesWithIncorrectReferencesFail {
303303
FIRFirestore *db2 = [self firestore];
304304
XCTAssertNotEqual(db1, db2);
305305

306-
NSString *reason = @"Provided document reference is from a different Firestore instance.";
306+
NSString *reason = @"Provided document reference is from a different Cloud Firestore instance.";
307307
id data = @{@"foo" : @1};
308308
FIRDocumentReference *badRef = [db2 documentWithPath:@"foo/bar"];
309309
FIRWriteBatch *batch = [db1 batch];
@@ -318,7 +318,7 @@ - (void)testTransactionWritesWithIncorrectReferencesFail {
318318
FIRFirestore *db2 = [self firestore];
319319
XCTAssertNotEqual(db1, db2);
320320

321-
NSString *reason = @"Provided document reference is from a different Firestore instance.";
321+
NSString *reason = @"Provided document reference is from a different Cloud Firestore instance.";
322322
id data = @{@"foo" : @1};
323323
FIRDocumentReference *badRef = [db2 documentWithPath:@"foo/bar"];
324324

Firestore/Source/API/FIRTransaction.mm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ - (FIRDocumentSnapshot *_Nullable)getDocument:(FIRDocumentReference *)document
178178

179179
- (void)validateReference:(FIRDocumentReference *)reference {
180180
if (reference.firestore != self.firestore) {
181-
ThrowInvalidArgument("Provided document reference is from a different Firestore instance.");
181+
ThrowInvalidArgument("Provided document reference is from a different Cloud Firestore "
182+
"instance.");
182183
}
183184
}
184185

Firestore/core/src/api/document_reference.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "Firestore/core/src/model/precondition.h"
3535
#include "Firestore/core/src/model/resource_path.h"
3636
#include "Firestore/core/src/util/error_apple.h"
37+
#include "Firestore/core/src/util/firestore_exceptions.h"
3738
#include "Firestore/core/src/util/hard_assert.h"
3839
#include "Firestore/core/src/util/hashing.h"
3940
#include "Firestore/core/src/util/status.h"
@@ -62,7 +63,7 @@ DocumentReference::DocumentReference(model::ResourcePath path,
6263
std::shared_ptr<Firestore> firestore)
6364
: firestore_{std::move(firestore)} {
6465
if (path.size() % 2 != 0) {
65-
HARD_FAIL(
66+
util::ThrowInvalidArgument(
6667
"Invalid document reference. Document references must have an even "
6768
"number of segments, but %s has %s",
6869
path.CanonicalString(), path.size());

Firestore/core/src/api/firestore.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,17 @@ const Settings& Firestore::settings() const {
104104
void Firestore::set_settings(const Settings& settings) {
105105
std::lock_guard<std::mutex> lock{mutex_};
106106
if (client_) {
107-
HARD_FAIL(
107+
util::ThrowIllegalState(
108108
"Firestore instance has already been started and its settings can "
109109
"no longer be changed. You can only set settings before calling any "
110110
"other methods on a Firestore instance.");
111111
}
112+
if (!settings.ssl_enabled() && settings.host() == Settings::DefaultHost) {
113+
util::ThrowIllegalState(
114+
"You can't set the 'sslEnabled' setting unless you also set a "
115+
"non-default 'host'.");
116+
}
117+
112118
settings_ = settings;
113119
}
114120

Firestore/core/src/api/write_batch.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ void WriteBatch::VerifyNotCommitted() const {
8080
void WriteBatch::ValidateReference(const DocumentReference& reference) const {
8181
if (reference.firestore() != firestore_) {
8282
ThrowInvalidArgument(
83-
"Provided document reference is from a different "
84-
"Firestore instance.");
83+
"Provided document reference is from a different Cloud Firestore "
84+
"instance.");
8585
}
8686
}
8787

Firestore/core/src/model/resource_path.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
#include <utility>
2121
#include <vector>
2222

23-
#include "Firestore/core/src/util/hard_assert.h"
23+
#include "Firestore/core/src/util/exception.h"
24+
#include "absl/strings/match.h"
2425
#include "absl/strings/str_join.h"
2526
#include "absl/strings/str_split.h"
2627

@@ -37,8 +38,10 @@ ResourcePath ResourcePath::FromStringView(absl::string_view path) {
3738
// sequences (e.g. __id123__) and just passes them through raw (they exist
3839
// for legacy reasons and should not be used frequently).
3940

40-
HARD_ASSERT(path.find("//") == std::string::npos,
41-
"Invalid path (%s). Paths must not contain // in them.", path);
41+
if (absl::StrContains(path, "//")) {
42+
util::ThrowInvalidArgument(
43+
"Invalid path (%s). Paths must not contain // in them.", path);
44+
}
4245

4346
// SkipEmpty because we may still have an empty segment at the beginning or
4447
// end if they had a leading or trailing slash (which we allow).

Firestore/core/src/util/exception.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,23 @@ ABSL_ATTRIBUTE_NORETURN void DefaultThrowHandler(ExceptionType type,
5252
}
5353
absl::StrAppend(&what, message);
5454

55+
// Always log the error -- it helps if there are any issues with the exception
56+
// propagation mechanism and also makes sure the exception makes it into the
57+
// log regardless of how it's handled.
58+
LOG_ERROR("%s", what);
59+
5560
#if ABSL_HAVE_EXCEPTIONS
5661
switch (type) {
5762
case ExceptionType::AssertionFailure:
5863
throw FirestoreInternalError(what);
5964
case ExceptionType::IllegalState:
60-
throw std::logic_error(what);
65+
// Omit descriptive text since the type already encodes the kind of error.
66+
throw std::logic_error(message);
6167
case ExceptionType::InvalidArgument:
62-
throw std::invalid_argument(what);
68+
// Omit descriptive text since the type already encodes the kind of error.
69+
throw std::invalid_argument(message);
6370
}
6471
#else
65-
LOG_ERROR("%s", what);
6672
std::terminate();
6773
#endif
6874

0 commit comments

Comments
 (0)