Index: src/wp-admin/includes/comment.php
===================================================================
--- src/wp-admin/includes/comment.php	(revision 40927)
+++ src/wp-admin/includes/comment.php	(working copy)
@@ -82,7 +82,11 @@
 		$_POST['comment_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
 	}
 
-	wp_update_comment( $_POST );
+	$result = wp_update_comment( $_POST, true );
+
+	if ( is_wp_error( $result ) ) {
+		wp_die ( $result->get_error_message() );
+	}
 }
 
 /**
Index: src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
===================================================================
--- src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php	(revision 40927)
+++ src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php	(working copy)
@@ -724,10 +724,10 @@
 				return new WP_Error( $error_code, __( 'Comment field exceeds maximum length allowed.' ), array( 'status' => 400 ) );
 			}
 
-			$updated = wp_update_comment( wp_slash( (array) $prepared_args ) );
+			$updated = wp_update_comment( wp_slash( (array) $prepared_args ), true );
 
-			if ( false === $updated ) {
-				return new WP_Error( 'rest_comment_failed_edit', __( 'Updating comment failed.' ), array( 'status' => 500 ) );
+			if ( is_wp_error( $updated ) ) {
+				return new WP_Error( 'rest_comment_failed_edit', $updated->get_error_message(), array( 'status' => 500 ) );
 			}
 
 			if ( isset( $request['status'] ) ) {
Index: src/wp-includes/comment.php
===================================================================
--- src/wp-includes/comment.php	(revision 40927)
+++ src/wp-includes/comment.php	(working copy)
@@ -2130,20 +2130,21 @@
  * @global wpdb $wpdb WordPress database abstraction object.
  *
  * @param array $commentarr Contains information on the comment.
- * @return int Comment was updated if value is 1, or was not updated if value is 0.
+ * @param bool  $wp_error Optional. Whether to return a WP_Error on failure. Default false
+ * @return int|bool|WP_Error Number of comment rows updated on success (0 or 1), false or WP_Error on failure.
  */
-function wp_update_comment($commentarr) {
+function wp_update_comment( $commentarr, $wp_error = false ) {
 	global $wpdb;
 
 	// First, get all of the original fields
 	$comment = get_comment($commentarr['comment_ID'], ARRAY_A);
 	if ( empty( $comment ) ) {
-		return 0;
+		return $wp_error ? new WP_Error( 'invalid_comment_id', __( 'Invalid comment ID.' ) ) : false;
 	}
 
 	// Make sure that the comment post ID is valid (if specified).
 	if ( ! empty( $commentarr['comment_post_ID'] ) && ! get_post( $commentarr['comment_post_ID'] ) ) {
-		return 0;
+		return $wp_error ? new WP_Error( 'invalid_post_id', __( 'Invalid post ID.' ) ) : false;
 	}
 
 	// Escape data pulled from DB.
@@ -2194,10 +2195,17 @@
 	 */
 	$data = apply_filters( 'wp_update_comment_data', $data, $comment, $commentarr );
 
+	if ( is_wp_error( $data ) ) { 
+ 		return $wp_error ? $data : false;
+	} 
+
 	$keys = array( 'comment_post_ID', 'comment_content', 'comment_author', 'comment_author_email', 'comment_approved', 'comment_karma', 'comment_author_url', 'comment_date', 'comment_date_gmt', 'comment_type', 'comment_parent', 'user_id', 'comment_agent', 'comment_author_IP' );
 	$data = wp_array_slice_assoc( $data, $keys );
 
 	$rval = $wpdb->update( $wpdb->comments, $data, compact( 'comment_ID' ) );
+	if ( false === $rval ) {
+		return $wp_error ? new WP_Error( 'db_update_error', __( 'Could not update comment in the database' ), $wpdb->last_error ) : false;
+	}
 
 	clean_comment_cache( $comment_ID );
 	wp_update_comment_count( $comment_post_ID );
Index: src/wp-includes/class-wp-xmlrpc-server.php
===================================================================
--- src/wp-includes/class-wp-xmlrpc-server.php	(revision 40927)
+++ src/wp-includes/class-wp-xmlrpc-server.php	(working copy)
@@ -3567,7 +3567,7 @@
 		// We've got all the data -- post it:
 		$comment = compact('comment_ID', 'comment_content', 'comment_approved', 'comment_date', 'comment_date_gmt', 'comment_author', 'comment_author_email', 'comment_author_url');
 
-		$result = wp_update_comment($comment);
+		$result = wp_update_comment( $comment, true );
 		if ( is_wp_error( $result ) )
 			return new IXR_Error(500, $result->get_error_message());
 
Index: tests/phpunit/tests/comment.php
===================================================================
--- tests/phpunit/tests/comment.php	(revision 40927)
+++ tests/phpunit/tests/comment.php	(working copy)
@@ -762,4 +762,23 @@
 
 		$this->assertSame( '1', $comment->comment_approved );
 	}
+
+	/**
+	 * @ticket 39732
+	 */
+	public function test_wp_update_comment_is_wp_error () {
+		$comment_id = self::factory()->comment->create( array( 'comment_post_ID' => self::$post_id ) );
+
+		add_filter( 'wp_update_comment_data', array( $this, '_wp_update_comment_data_filter' ), 10, 3 );
+		$result = wp_update_comment( array( 'comment_ID' => $comment_id, 'comment_type' => 'pingback' ), true );
+		$this->assertWPError( $result );
+		remove_filter( 'wp_update_comment_data', array( $this, '_wp_update_comment_data_filter' ), 10, 3 );
+	}
+
+	/**
+	 *  Block comments from being updated by returning WP_Error
+	 */
+	public function _wp_update_comment_data_filter ( $data, $comment, $commentarr ) {
+		return new WP_Error( 'comment_wrong', __( 'wp_update_comment_data filter fails for this comment.' ), 500 );
+	}
 }
Index: tests/phpunit/tests/xmlrpc/wp/editComment.php
===================================================================
--- tests/phpunit/tests/xmlrpc/wp/editComment.php	(revision 40927)
+++ tests/phpunit/tests/xmlrpc/wp/editComment.php	(working copy)
@@ -69,4 +69,36 @@
 
 		$this->assertEquals( 'trash', get_comment( $comment_id )->comment_approved );
 	}
+
+	/**
+	 * @ticket 39732
+	 */
+	public function test__wp_update_comment_data_filter () {
+		$author_id = $this->make_user_by_role( 'author' );
+		$post_id = self::factory()->post->create( array(
+			'post_title' => 'Post test by author',
+			'post_author' => $author_id
+		) );
+
+		$comment_id = wp_insert_comment(array(
+			'comment_post_ID' => $post_id,
+			'comment_author' => 'Commenter 1',
+			'comment_author_url' => "http://example.com/1/",
+			'comment_approved' => 1,
+		));
+
+		add_filter( 'wp_update_comment_data', array( $this, '_wp_update_comment_data_filter' ), 10, 3 );
+		$result = $this->myxmlrpcserver->wp_editComment( array( 1, 'author', 'author', $comment_id, array( 'status' => 'hold' ) ) );
+
+		$this->assertIXRError( $result );
+		$this->assertEquals( 500, $result->code );
+		$this->assertEquals( __( 'wp_update_comment_data filter fails for this comment.' ), $result->message );	
+	}
+
+	/**
+	 *  Block comments from being updated by returning WP_Error
+	 */
+	public function _wp_update_comment_data_filter ( $data, $comment, $commentarr ) {
+		return new WP_Error( 'comment_wrong', __( 'wp_update_comment_data filter fails for this comment.' ), 500 );
+	}
 }
Index: tests/phpunit/tests/ajax/EditComment.php
===================================================================
--- tests/phpunit/tests/ajax/EditComment.php	(revision 40927)
+++ tests/phpunit/tests/ajax/EditComment.php	(working copy)
@@ -191,4 +191,41 @@
 		$this->setExpectedException( 'WPAjaxDieStopException', '-1' );
 		$this->_handleAjax( 'edit-comment' );
 	}
+
+	/**
+	 * @ticket 39732
+	 */
+	public function test_wp_update_comment_data_is_wp_error () {
+		
+		// Become an administrator
+		$this->_setRole( 'administrator' );
+
+		// Get a comment
+		$comments = get_comments( array(
+			'post_id' => $this->_comment_post->ID
+		) );
+		$comment = array_pop( $comments );
+
+		// Set up a default request
+		$_POST['_ajax_nonce-replyto-comment'] = wp_create_nonce( 'replyto-comment' );
+		$_POST['comment_ID']                  = $comment->comment_ID;
+		$_POST['content']                     = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
+
+		// Simulate filter check error
+		add_filter( 'wp_update_comment_data', array( $this, '_wp_update_comment_data_filter' ), 10, 3 );
+
+		// Make the request
+		$this->setExpectedException( 'WPAjaxDieStopException', 'wp_update_comment_data filter fails for this comment.' );
+		$this->_handleAjax( 'edit-comment' );
+		
+		remove_filter( 'wp_update_comment_data', array( $this, '_wp_update_comment_data_filter' ), 10, 3 );
+		
+	}
+	
+	/**
+	 *  Block comments from being updated by returning WP_Error
+	 */
+	public function _wp_update_comment_data_filter ( $data, $comment, $commentarr ) {
+		return new WP_Error( 'comment_wrong', __( 'wp_update_comment_data filter fails for this comment.' ), 500 );
+	}
 }
Index: tests/phpunit/tests/rest-api/rest-comments-controller.php
===================================================================
--- tests/phpunit/tests/rest-api/rest-comments-controller.php	(revision 40927)
+++ tests/phpunit/tests/rest-api/rest-comments-controller.php	(working copy)
@@ -2514,6 +2514,34 @@
 		$this->assertErrorResponse( 'comment_content_column_length', $response, 400 );
 	}
 
+	/**
+	 * @ticket 39732
+	 */
+	public function test_update_comment_is_wp_error() {
+		wp_set_current_user( self::$admin_id );
+
+		$params = array(
+			'content'     => 'This isn\'t a saxophone. It\'s an umbrella.',
+		);
+
+		add_filter( 'wp_update_comment_data', array( $this, '_wp_update_comment_data_filter' ), 10, 3 );
+
+		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d', self::$approved_id ) );
+
+		$request->add_header( 'content-type', 'application/json' );
+		$request->set_body( wp_json_encode( $params ) );
+		$response = $this->server->dispatch( $request );
+
+		$this->assertErrorResponse( 'rest_comment_failed_edit', $response, 500 );
+	}
+
+	/**
+	 *  Block comments from being updated by returning WP_Error
+	 */
+	public function _wp_update_comment_data_filter ( $data, $comment, $commentarr ) {
+		return new WP_Error( 'comment_wrong', __( 'wp_update_comment_data filter fails for this comment.' ), array( 'status' => 500 ) );
+	}
+
 	public function verify_comment_roundtrip( $input = array(), $expected_output = array() ) {
 		// Create the comment
 		$request = new WP_REST_Request( 'POST', '/wp/v2/comments' );
