diff --git a/mercurial/mpatch.c b/mercurial/mpatch.c
--- a/mercurial/mpatch.c
+++ b/mercurial/mpatch.c
@@ -404,7 +404,8 @@ PyMODINIT_FUNC PyInit_mpatch(void)
 	if (m == NULL)
 		return NULL;
 
-	mpatch_Error = PyErr_NewException("mpatch.mpatchError", NULL, NULL);
+	mpatch_Error = PyErr_NewException("mercurial.mpatch.mpatchError",
+					  NULL, NULL);
 	Py_INCREF(mpatch_Error);
 	PyModule_AddObject(m, "mpatchError", mpatch_Error);
 
@@ -415,6 +416,7 @@ PyMODINIT_FUNC
 initmpatch(void)
 {
 	Py_InitModule3("mpatch", methods, mpatch_doc);
-	mpatch_Error = PyErr_NewException("mpatch.mpatchError", NULL, NULL);
+	mpatch_Error = PyErr_NewException("mercurial.mpatch.mpatchError",
+					  NULL, NULL);
 }
 #endif
diff --git a/mercurial/pure/mpatch.py b/mercurial/pure/mpatch.py
--- a/mercurial/pure/mpatch.py
+++ b/mercurial/pure/mpatch.py
@@ -12,6 +12,10 @@ import struct
 
 StringIO = cStringIO.StringIO
 
+class mpatchError(Exception):
+    """error raised when a delta cannot be decoded
+    """
+
 # This attempts to apply a series of patches in time proportional to
 # the total size of the patches, rather than patches * len(text). This
 # means rather than shuffling strings around, we shuffle around
@@ -84,7 +88,10 @@ def patches(a, bins):
         last = 0
         while pos < end:
             m.seek(pos)
-            p1, p2, l = struct.unpack(">lll", m.read(12))
+            try:
+                p1, p2, l = struct.unpack(">lll", m.read(12))
+            except struct.error:
+                raise mpatchError("patch cannot be decoded")
             _pull(new, frags, p1 - last) # what didn't change
             _pull([], frags, p2 - p1)    # what got deleted
             new.append((l, pos + 12))   # what got added
@@ -114,7 +121,7 @@ def patchedsize(orig, delta):
         outlen += length
 
     if bin != binend:
-        raise ValueError("patch cannot be decoded")
+        raise mpatchError("patch cannot be decoded")
 
     outlen += orig - last
     return outlen
diff --git a/tests/test-revlog.t b/tests/test-revlog.t
--- a/tests/test-revlog.t
+++ b/tests/test-revlog.t
@@ -11,5 +11,5 @@ Test for CVE-2016-3630
      rev    offset  length  delta linkrev nodeid       p1           p2
        0         0      19     -1       2 99e0332bd498 000000000000 000000000000
        1        19      12      0       3 6674f57a23d8 99e0332bd498 000000000000
-  $ hg debugdata a.i 1 2>&1 | grep decoded
-  mpatch.mpatchError: patch cannot be decoded
+  $ hg debugdata a.i 1 2>&1 | egrep 'Error:.*decoded'
+  mercurial.mpatch.mpatchError: patch cannot be decoded