Browse Source

Merge pull request #796 from paullouisageneau/catch-user-cb-exceptions

Catch exceptions from user callbacks early
Paul-Louis Ageneau 2 years ago
parent
commit
c91f0df4f6
3 changed files with 58 additions and 11 deletions
  1. 39 8
      src/impl/channel.cpp
  2. 14 2
      src/impl/peerconnection.cpp
  3. 5 1
      src/impl/peerconnection.hpp

+ 39 - 8
src/impl/channel.cpp

@@ -7,22 +7,44 @@
  */
 
 #include "channel.hpp"
+#include "internals.hpp"
 
 namespace rtc::impl {
 
 void Channel::triggerOpen() {
 	mOpenTriggered = true;
-	openCallback();
+	try {
+		openCallback();
+	} catch (const std::exception &e) {
+		PLOG_WARNING << "Uncaught exception in callback: " << e.what();
+	}
 	flushPendingMessages();
 }
 
-void Channel::triggerClosed() { closedCallback(); }
+void Channel::triggerClosed() {
+	try {
+		closedCallback();
+	} catch (const std::exception &e) {
+		PLOG_WARNING << "Uncaught exception in callback: " << e.what();
+	}
+}
 
-void Channel::triggerError(string error) { errorCallback(std::move(error)); }
+void Channel::triggerError(string error) {
+	try {
+		errorCallback(std::move(error));
+	} catch (const std::exception &e) {
+		PLOG_WARNING << "Uncaught exception in callback: " << e.what();
+	}
+}
 
 void Channel::triggerAvailable(size_t count) {
-	if (count == 1)
-		availableCallback();
+	if (count == 1) {
+		try {
+			availableCallback();
+		} catch (const std::exception &e) {
+			PLOG_WARNING << "Uncaught exception in callback: " << e.what();
+		}
+	}
 
 	flushPendingMessages();
 }
@@ -30,8 +52,13 @@ void Channel::triggerAvailable(size_t count) {
 void Channel::triggerBufferedAmount(size_t amount) {
 	size_t previous = bufferedAmount.exchange(amount);
 	size_t threshold = bufferedAmountLowThreshold.load();
-	if (previous > threshold && amount <= threshold)
-		bufferedAmountLowCallback();
+	if (previous > threshold && amount <= threshold) {
+		try {
+			bufferedAmountLowCallback();
+		} catch (const std::exception &e) {
+			PLOG_WARNING << "Uncaught exception in callback: " << e.what();
+		}
+	}
 }
 
 void Channel::flushPendingMessages() {
@@ -43,7 +70,11 @@ void Channel::flushPendingMessages() {
 		if (!next)
 			break;
 
-		messageCallback(*next);
+		try {
+			messageCallback(*next);
+		} catch (const std::exception &e) {
+			PLOG_WARNING << "Uncaught exception in callback: " << e.what();
+		}
 	}
 }
 

+ 14 - 2
src/impl/peerconnection.cpp

@@ -1094,7 +1094,13 @@ void PeerConnection::triggerPendingDataChannels() {
 			break;
 
 		auto impl = std::move(*next);
-		dataChannelCallback(std::make_shared<rtc::DataChannel>(impl));
+
+		try {
+			dataChannelCallback(std::make_shared<rtc::DataChannel>(impl));
+		} catch (const std::exception &e) {
+			PLOG_WARNING << "Uncaught exception in callback: " << e.what();
+		}
+
 		impl->triggerOpen();
 	}
 }
@@ -1106,7 +1112,13 @@ void PeerConnection::triggerPendingTracks() {
 			break;
 
 		auto impl = std::move(*next);
-		trackCallback(std::make_shared<rtc::Track>(impl));
+
+		try {
+			trackCallback(std::make_shared<rtc::Track>(impl));
+		} catch (const std::exception &e) {
+			PLOG_WARNING << "Uncaught exception in callback: " << e.what();
+		}
+
 		// Do not trigger open immediately for tracks as it'll be done later
 	}
 }

+ 5 - 1
src/impl/peerconnection.hpp

@@ -96,7 +96,11 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
 
 	// Helper method for asynchronous callback invocation
 	template <typename... Args> void trigger(synchronized_callback<Args...> *cb, Args... args) {
-		(*cb)(std::move(args...));
+		try {
+			(*cb)(std::move(args...));
+		} catch (const std::exception &e) {
+			PLOG_WARNING << "Uncaught exception in callback: " << e.what();
+		}
 	}
 
 	const Configuration config;