ExceptionConverter.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <?php
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. */
  15. namespace Alcaeus\MongoDbAdapter;
  16. use MongoDB\Driver\Exception;
  17. use MongoDB\Driver\WriteError;
  18. use MongoDB\Driver\WriteResult;
  19. /**
  20. * @internal
  21. */
  22. class ExceptionConverter
  23. {
  24. /**
  25. * @param Exception\Exception $e
  26. * @param string $fallbackClass
  27. *
  28. * @return \MongoException
  29. */
  30. public static function toLegacy(Exception\Exception $e, $fallbackClass = 'MongoException')
  31. {
  32. // Starting with ext-mongodb 1.6.0, errors during bulk write are always wrapped in a BulkWriteException.
  33. // If a BulkWriteException wraps another driver exception, use that instead.
  34. if ($e instanceof Exception\BulkWriteException && $e->getPrevious() instanceof Exception\Exception) {
  35. $e = $e->getPrevious();
  36. }
  37. $message = $e->getMessage();
  38. $code = $e->getCode();
  39. switch (get_class($e)) {
  40. case Exception\AuthenticationException::class:
  41. case Exception\ConnectionException::class:
  42. case Exception\ConnectionTimeoutException::class:
  43. case Exception\SSLConnectionException::class:
  44. $class = 'MongoConnectionException';
  45. break;
  46. case Exception\BulkWriteException::class:
  47. case Exception\WriteException::class:
  48. $writeResult = $e->getWriteResult();
  49. // attempt to retrieve write error
  50. if ($writeResult instanceof WriteResult && is_array($writeResult->getWriteErrors()) && $writeResult->getWriteErrors() !== []) {
  51. $writeError = $writeResult->getWriteErrors()[0];
  52. if ($writeError instanceof WriteError) {
  53. $message = $writeError->getMessage();
  54. $code = $writeError->getCode();
  55. }
  56. }
  57. switch ($code) {
  58. // see https://github.com/mongodb/mongo-php-driver-legacy/blob/ad3ed45739e9702ae48e53ddfadc482d9c4c7e1c/cursor_shared.c#L540
  59. case 11000:
  60. case 11001:
  61. case 12582:
  62. $class = 'MongoDuplicateKeyException';
  63. break;
  64. default:
  65. $class = 'MongoCursorException';
  66. }
  67. break;
  68. case Exception\ExecutionTimeoutException::class:
  69. $class = 'MongoExecutionTimeoutException';
  70. break;
  71. default:
  72. $class = $fallbackClass;
  73. }
  74. if (strpos($message, 'No suitable servers found') !== false) {
  75. return new \MongoConnectionException($message, $code, $e);
  76. }
  77. if ($message === "cannot use 'w' > 1 when a host is not replicated") {
  78. return new \MongoWriteConcernException($message, $code, $e);
  79. }
  80. return new $class($message, $code, $e);
  81. }
  82. /**
  83. * Converts an exception to
  84. *
  85. * @param Exception\Exception $e
  86. * @return array
  87. */
  88. public static function toResultArray(Exception\Exception $e)
  89. {
  90. return [
  91. 'ok' => 0.0,
  92. 'errmsg' => $e->getMessage(),
  93. 'code' => $e->getCode(),
  94. ];
  95. }
  96. }