Fix unicode error when sending confirmation email in shopping cart
Wrap send email operation in try/except to avoid rolling back the transaction once a user has paid.
This commit is contained in:
@@ -481,10 +481,18 @@ class Order(models.Model):
|
||||
log.exception('Exception at creating pdf file.')
|
||||
pdf_file = None
|
||||
|
||||
self.send_confirmation_emails(
|
||||
orderitems, self.order_type == OrderTypes.BUSINESS,
|
||||
csv_file, pdf_file, site_name, courses_info
|
||||
)
|
||||
try:
|
||||
self.send_confirmation_emails(
|
||||
orderitems, self.order_type == OrderTypes.BUSINESS,
|
||||
csv_file, pdf_file, site_name, courses_info
|
||||
)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
# Catch all exceptions here, since the Django view implicitly
|
||||
# wraps this in a transaction. If the order completes successfully,
|
||||
# we don't want to roll back just because we couldn't send
|
||||
# the confirmation email.
|
||||
log.exception('Error occurred while sending payment confirmation email')
|
||||
|
||||
self._emit_order_event('Completed Order', orderitems)
|
||||
|
||||
def refund(self):
|
||||
@@ -1460,7 +1468,9 @@ class CertificateItem(OrderItem):
|
||||
"If you haven't verified your identity yet, please start the verification process ({verification_url})."
|
||||
).format(verification_url=verification_url)
|
||||
|
||||
return "{verification_reminder} {refund_reminder}".format(
|
||||
# Need this to be unicode in case the reminder strings
|
||||
# have been translated and contain non-ASCII unicode
|
||||
return u"{verification_reminder} {refund_reminder}".format(
|
||||
verification_reminder=verification_reminder,
|
||||
refund_reminder=refund_reminder
|
||||
)
|
||||
|
||||
@@ -375,6 +375,34 @@ class OrderTest(ModuleStoreTestCase):
|
||||
cart.generate_receipt_instructions()
|
||||
mock_gen_inst.assert_called_with()
|
||||
|
||||
def test_confirmation_email_error(self):
|
||||
CourseMode.objects.create(
|
||||
course_id=self.course_key,
|
||||
mode_slug="verified",
|
||||
mode_display_name="Verified",
|
||||
min_price=self.cost
|
||||
)
|
||||
|
||||
cart = Order.get_cart_for_user(self.user)
|
||||
CertificateItem.add_to_order(cart, self.course_key, self.cost, 'verified')
|
||||
|
||||
# Simulate an error when sending the confirmation
|
||||
# email. This should NOT raise an exception.
|
||||
# If it does, then the implicit view-level
|
||||
# transaction could cause a roll-back, effectively
|
||||
# reversing order fulfillment.
|
||||
with patch.object(mail.message.EmailMessage, 'send') as mock_send:
|
||||
mock_send.side_effect = Exception("Kaboom!")
|
||||
cart.purchase()
|
||||
|
||||
# Verify that the purchase completed successfully
|
||||
self.assertEqual(cart.status, 'purchased')
|
||||
|
||||
# Verify that the user is enrolled as "verified"
|
||||
mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course_key)
|
||||
self.assertTrue(is_active)
|
||||
self.assertEqual(mode, 'verified')
|
||||
|
||||
|
||||
class OrderItemTest(TestCase):
|
||||
def setUp(self):
|
||||
|
||||
Reference in New Issue
Block a user