Return an error when datachannel closes due to network error
This is the start of generating compliant errors, including diagnostics,
when datachannels close because of errors.
Bug: chromium:1030631
Change-Id: I39aa41728efb25bca6193a782db4cbdaad8e0dc1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161304
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30034}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index acc2bd7..45f555c 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -229,6 +229,7 @@
"../rtc_base:logging",
"../rtc_base:macromagic",
"../rtc_base/system:rtc_export",
+ "//third_party/abseil-cpp/absl/types:optional",
]
}
diff --git a/api/data_channel_interface.h b/api/data_channel_interface.h
index ccf3ad7..e08830f 100644
--- a/api/data_channel_interface.h
+++ b/api/data_channel_interface.h
@@ -20,6 +20,7 @@
#include <string>
#include "absl/types/optional.h"
+#include "api/rtc_error.h"
#include "rtc_base/checks.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/ref_count.h"
@@ -154,6 +155,10 @@
// determined, and until then this will return -1.
virtual int id() const = 0;
virtual DataState state() const = 0;
+ // When state is kClosed, and the DataChannel was not closed using
+ // the closing procedure, returns the error information about the closing.
+ // The default implementation returns "no error".
+ virtual RTCError error() const { return RTCError(); }
virtual uint32_t messages_sent() const = 0;
virtual uint64_t bytes_sent() const = 0;
virtual uint32_t messages_received() const = 0;
diff --git a/api/rtc_error.cc b/api/rtc_error.cc
index c9ad7cb..4d3033b 100644
--- a/api/rtc_error.cc
+++ b/api/rtc_error.cc
@@ -26,19 +26,34 @@
"NETWORK_ERROR",
"RESOURCE_EXHAUSTED",
"INTERNAL_ERROR",
+ "OPERATION_ERROR_WITH_DATA",
};
-static_assert(static_cast<int>(webrtc::RTCErrorType::INTERNAL_ERROR) ==
- (arraysize(kRTCErrorTypeNames) - 1),
- "kRTCErrorTypeNames must have as many strings as RTCErrorType "
- "has values.");
+static_assert(
+ static_cast<int>(webrtc::RTCErrorType::OPERATION_ERROR_WITH_DATA) ==
+ (arraysize(kRTCErrorTypeNames) - 1),
+ "kRTCErrorTypeNames must have as many strings as RTCErrorType "
+ "has values.");
+
+const char* kRTCErrorDetailTypeNames[] = {
+ "NONE",
+ "DATA_CHANNEL_FAILURE",
+ "DTLS_FAILURE",
+ "FINGERPRINT_FAILURE",
+ "SCTP_FAILURE",
+ "SDP_SYNTAX_ERROR",
+ "HARDWARE_ENCODER_NOT_AVAILABLE",
+ "HARDWARE_ENCODER_ERROR",
+};
+static_assert(
+ static_cast<int>(webrtc::RTCErrorDetailType::HARDWARE_ENCODER_ERROR) ==
+ (arraysize(kRTCErrorDetailTypeNames) - 1),
+ "kRTCErrorDetailTypeNames must have as many strings as "
+ "RTCErrorDetailType has values.");
} // namespace
namespace webrtc {
-RTCError::RTCError(RTCError&& other) = default;
-RTCError& RTCError::operator=(RTCError&& other) = default;
-
// static
RTCError RTCError::OK() {
return RTCError();
@@ -57,4 +72,9 @@
return kRTCErrorTypeNames[index];
}
+const char* ToString(RTCErrorDetailType error) {
+ int index = static_cast<int>(error);
+ return kRTCErrorDetailTypeNames[index];
+}
+
} // namespace webrtc
diff --git a/api/rtc_error.h b/api/rtc_error.h
index 970507f..0e264af 100644
--- a/api/rtc_error.h
+++ b/api/rtc_error.h
@@ -17,6 +17,7 @@
#include <string>
#include <utility> // For std::move.
+#include "absl/types/optional.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/system/rtc_export.h"
@@ -73,6 +74,25 @@
// The operation failed due to an internal error.
// Maps to OperationError DOMException.
INTERNAL_ERROR,
+
+ // An error occured that has additional data.
+ // The additional data is specified in
+ // https://w3c.github.io/webrtc-pc/#rtcerror-interface
+ // Maps to RTCError DOMException.
+ OPERATION_ERROR_WITH_DATA,
+};
+
+// Detail information, showing what further information should be present.
+// https://w3c.github.io/webrtc-pc/#rtcerrordetailtype-enum
+enum class RTCErrorDetailType {
+ NONE,
+ DATA_CHANNEL_FAILURE,
+ DTLS_FAILURE,
+ FINGERPRINT_FAILURE,
+ SCTP_FAILURE,
+ SDP_SYNTAX_ERROR,
+ HARDWARE_ENCODER_NOT_AVAILABLE,
+ HARDWARE_ENCODER_ERROR,
};
// Roughly corresponds to RTCError in the web api. Holds an error type, a
@@ -91,15 +111,11 @@
RTCError(RTCErrorType type, std::string message)
: type_(type), message_(std::move(message)) {}
- // Delete the copy constructor and assignment operator; there aren't any use
- // cases where you should need to copy an RTCError, as opposed to moving it.
- // Can revisit this decision if use cases arise in the future.
- RTCError(const RTCError& other) = delete;
- RTCError& operator=(const RTCError& other) = delete;
-
- // Move constructor and move-assignment operator.
- RTCError(RTCError&& other);
- RTCError& operator=(RTCError&& other);
+ // In many use cases, it is better to use move than copy,
+ // but copy and assignment are provided for those cases that need it.
+ // Note that this has extra overhead because it copies strings.
+ RTCError(const RTCError& other) = default;
+ RTCError& operator=(const RTCError& other) = default;
// Identical to default constructed error.
//
@@ -117,6 +133,13 @@
void set_message(std::string message);
+ RTCErrorDetailType error_detail() const { return error_detail_; }
+ void set_error_detail(RTCErrorDetailType detail) { error_detail_ = detail; }
+ absl::optional<uint16_t> sctp_cause_code() { return sctp_cause_code_; }
+ void set_sctp_cause_code(uint16_t cause_code) {
+ sctp_cause_code_ = cause_code;
+ }
+
// Convenience method for situations where you only care whether or not an
// error occurred.
bool ok() const { return type_ == RTCErrorType::NONE; }
@@ -124,6 +147,8 @@
private:
RTCErrorType type_ = RTCErrorType::NONE;
std::string message_;
+ RTCErrorDetailType error_detail_ = RTCErrorDetailType::NONE;
+ absl::optional<uint16_t> sctp_cause_code_;
};
// Outputs the error as a friendly string. Update this method when adding a new
@@ -132,6 +157,7 @@
// Only intended to be used for logging/diagnostics. The returned char* points
// to literal string that lives for the whole duration of the program.
RTC_EXPORT const char* ToString(RTCErrorType error);
+RTC_EXPORT const char* ToString(RTCErrorDetailType error);
#ifdef UNIT_TEST
inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
@@ -139,6 +165,12 @@
RTCErrorType error) {
return stream << ToString(error);
}
+
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ RTCErrorDetailType error) {
+ return stream << ToString(error);
+}
#endif // UNIT_TEST
// Helper macro that can be used by implementations to create an error with a