-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exception unification improvements #5911
Exception unification improvements #5911
Conversation
8dba10d
to
e665c4d
Compare
@tgoyne How much bigger is the binary now with this PR? |
Current sizes of Realm.framework:
|
7f33825
to
a2287ce
Compare
a2287ce
to
37f40e3
Compare
4c3fddb
to
fb7a3a1
Compare
ac0df23
to
ccc8a1d
Compare
// Create a deep copy of the file_path string, otherwise it can appear that | ||
// users are leaking paths because string assignment operator implementations might | ||
// actually be reference counting with copy-on-write. If our all_files map | ||
// holds onto these references (since it is still reachable memory) it can appear | ||
// as a leak in the user application, but it is actually us (and that's ok). | ||
const std::string path = file_path.c_str(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a workaround for a c++03 thing (copy-on-write std::string) which hasn't been applicable since c++11.
@@ -85,31 +85,35 @@ UnsupportedFileFormatVersion::UnsupportedFileFormatVersion(int version) | |||
UnsupportedFileFormatVersion::~UnsupportedFileFormatVersion() noexcept = default; | |||
|
|||
|
|||
LogicError::LogicError(ErrorCodes::Error code, const std::string& msg) | |||
LogicError::LogicError(ErrorCodes::Error code, std::string_view msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's one or two spots where being able to pass in a string_view is nice, and that ends up being a viral change that needs to propagate all the way downwards so it touches all of these.
@@ -122,11 +122,11 @@ ExternalCommitHelper::ExternalCommitHelper(RealmCoordinator& parent, const Realm | |||
std::string temp_dir = util::normalize_dir(config.fifo_files_fallback_path); | |||
std::string sys_temp_dir = util::normalize_dir(DBOptions::get_sys_tmp_dir()); | |||
path = DB::get_core_file(config.path, DB::CoreFileType::Note); | |||
bool fifo_created = realm::util::try_create_fifo(path); | |||
bool fifo_created = realm::util::try_create_fifo(path, !temp_dir.empty() || !sys_temp_dir.empty()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change here is making it only swallow the exception if we have more paths to try, which results in a more useful error when we can't create the fifo and don't have a fallback.
@@ -425,31 +425,6 @@ void RealmCoordinator::open_db() | |||
util::File::remove(m_config.path); | |||
return open_db(); | |||
} | |||
catch (const FileAccessError& ex) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This now is all handled in File::open()
@@ -154,7 +154,7 @@ void SyncSession::become_inactive(util::CheckedUniqueLock lock, Status status) | |||
} | |||
|
|||
if (!status.get_std_error_code()) | |||
status = Status(make_error_code(util::error::operation_aborted), "SyncSession::become_inactive"); | |||
status = Status(make_error_code(util::error::operation_aborted), "Sync session became inactive"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error is still not great but correctly reporting why the listener was cancelled turned out to be oddly complicated.
default: | ||
throw FileAccessError(ErrorCodes::FileOperationFailed, msg, path, err); // LCOV_EXCL_LINE | ||
} | ||
} | ||
|
||
|
||
void remove_dir_recursive(const std::string& path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wasn't actually used.
|
||
template <typename T> | ||
inline T get(Mixed) | ||
{ | ||
abort(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main goal of these changes is to eliminate these aborts and replace them with compile-time failures. As a bonus it ends up less verbose and actually compilers faster due to eliminating unreachable template instantiations.
0b2171b
to
6789384
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
6789384
to
0b00657
Compare
This turns some runtime failures for misuse into compile time failures and improves the compilation time of the tests a bit by eliminating a bunch of unreachable template instantiations.
If there was no temporary directory available and creating the fifo at the default path failed, it reported an error for trying to open the nonexistent fifo rather than creating the fifo failing.
0b00657
to
6e06cc6
Compare
Most of these changes are related to improving the messages in exceptions thrown by core so that we can pass them on directly to the user rather than having to replace them with better errors in the SDK. With these changes, there's only a small number of places where Cocoa modifies the messages thrown by core, and they're all clearly linked to Cocoa-specific quirks.
This also greatly expands the testing of the exceptions thrown by core, as there were a number of places where Cocoa tests identified errors with messages that were simply wrong. Every instance of
REQUIRE_THROWS()
in the object store tests has been replaced with a more precise assertion which validations that the expected thing is being thrown; in most cases withREQUIRE_EXCEPTION()
, which is a new test macro which checks that the exception is arealm::Exception
, has the expected error code, and validates the exception message (either using a literal string or a Catch matcher). This revealed a few places where tests weren't testing the thing they intended to test, many places where things other thanrealm::Exception
were being thrown, and a lot of spots where error messages could just be better.The binary size increased by quite a bit with the exception unification branch, so I made some localized changes to address this. Giving each of the exception types a non-inline virtual function makes it so that the vtables for the exception types aren't inline and thus aren't emitted into every since TU which includes the header (which is most of them). This cuts about a megabyte of a static library build. The
std::map
for converting error code names to codes also had surprisingly bad codegen due to building the map at runtime, and replacing it with a statically sorted array both reduces the size and improves startup perf.