diff --git a/lti_consumer/outcomes.py b/lti_consumer/outcomes.py
index 88c804b43ca574d87f500da6671d3ce2c5b388dd..049742aa9eb46520c88da534ae74fc5ab852370e 100644
--- a/lti_consumer/outcomes.py
+++ b/lti_consumer/outcomes.py
@@ -162,15 +162,16 @@ class OutcomeService(object):  # pylint: disable=bad-option-value, useless-objec
             'imsx_messageIdentifier': 'unknown',
             'response': ''
         }
+        request_body = request.body.decode('utf-8')
 
         if not self.xblock.accept_grades_past_due and self.xblock.is_past_due:
             failure_values['imsx_description'] = "Grade is past due"
             return response_xml_template.format(**failure_values)
 
         try:
-            imsx_message_identifier, sourced_id, score, action = parse_grade_xml_body(request.body)
+            imsx_message_identifier, sourced_id, score, action = parse_grade_xml_body(request_body)
         except LtiError as ex:  # pylint: disable=no-member
-            body = escape(request.body) if request.body else ''
+            body = escape(request_body) if request_body else ''
             error_message = "Request body XML parsing error: {} {}".format(str(ex), body)
             log.debug("[LTI]: %s", error_message)
             failure_values['imsx_description'] = error_message
diff --git a/lti_consumer/tests/unit/test_outcomes.py b/lti_consumer/tests/unit/test_outcomes.py
index 1ebb538ae2b419a7a33ab3fd52ff219da93d4509..56dd099643a59c9631971a78aa937538c3455aaa 100644
--- a/lti_consumer/tests/unit/test_outcomes.py
+++ b/lti_consumer/tests/unit/test_outcomes.py
@@ -370,6 +370,20 @@ class TestOutcomeService(TestLtiConsumerXBlock):
         self.assertIn('failure', response)
         self.assertIn('Grade is past due', response)
 
+    @patch('lti_consumer.outcomes.parse_grade_xml_body')
+    def test_lti_error_not_raises_type_error(self, mock_parse):
+        """
+        Test XML parsing LtiError exception doesn't raise TypeError exception
+        while escaping the request body.
+        """
+        request = make_request('test_string')
+
+        mock_parse.side_effect = LtiError
+        response = self.outcome_servce.handle_request(request)
+        self.assertNotIn('TypeError', response)
+        self.assertNotIn('a bytes-like object is required', response)
+        self.assertIn('Request body XML parsing error', response)
+
     @patch('lti_consumer.outcomes.parse_grade_xml_body')
     def test_xml_parse_lti_error(self, mock_parse):
         """