diff --git a/VERSIONS_WIP/62394 b/VERSIONS_WIP/62394
new file mode 100644
index 0000000000000000000000000000000000000000..041f99c29d5f521f0fa3de500db87dfc91f1b5eb
--- /dev/null
+++ b/VERSIONS_WIP/62394
@@ -0,0 +1 @@
+ - ticket #62394 : Webservice Koha : affichage des raisons des actions non possibles de prolongation et de réservation.
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/AbstractRESTService.php b/library/Class/WebService/SIGB/AbstractRESTService.php
index a485b4b9bf046f37d2375b1d3e2f2409fdde15a9..5fd75ff2e1f27ae892253ad8ee421da833f0d75a 100644
--- a/library/Class/WebService/SIGB/AbstractRESTService.php
+++ b/library/Class/WebService/SIGB/AbstractRESTService.php
@@ -135,14 +135,21 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
    */
   protected function _getTagData($xml, $tag) {
     $matches = array();
-    if (preg_match(sprintf('/%s>([^<]*)<\/%s/', $tag, $tag),
+    $string_to_search = sprintf('/%s>([^<]*)<\/%s/', $tag, $tag);
+    if (preg_match($string_to_search,
                    $xml,
-                   $matches))
+                   $matches)) {
       return $matches[1];
+    }
     return '';
   }
 
 
+  protected function _findErrorTagInXml($xml, $tag) {
+    return $this->_getTagData($xml,$tag);
+  }
+
+
   public function httpGetNotice($params, $reader) {
     $xml = $this->httpGet($params);
 
@@ -242,16 +249,22 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
 
 
   public function ilsdiCheckXml($xml, $error_tag, $error_message) {
+    return ($error = $this->_getErrorMessage($xml, $error_tag, $error_message))
+      ? $this->_error($error)
+      : $this->_success();
+  }
+
+
+  protected function _getErrorMessage($xml, $tag, $message) {
     if (!$xml)
-      return $this->_getNetworkError();
+      return $this->_getNetworkErrorLabel();
 
     if (0 === strpos($xml, '<html>'))
-      return $this->_getNetworkError();
-
-    if ($error_code = $this->_getTagData($xml, $error_tag))
-      return $this->_getErrorFromCode($error_code, $error_message);
+      return $this->_getNetworkErrorLabel();
 
-    return $this->_success();
+    return ($error = $this->_findErrorTagInXml($xml, $tag))
+      ? $this->_getErrorFromCode($error, $message)
+      : null;
   }
 
 
@@ -275,6 +288,6 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
 
 
   protected function _getErrorFromCode($error_code, $default_message) {
-    return $this->_error($default_message);
+    return $default_message;
   }
 }
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/Koha/Service.php b/library/Class/WebService/SIGB/Koha/Service.php
index a00fad26fb17ff573a976813f055a3e8cd75a09d..1890f779e5a2d2d96d3bdb2fbf1bcb92d15601c9 100644
--- a/library/Class/WebService/SIGB/Koha/Service.php
+++ b/library/Class/WebService/SIGB/Koha/Service.php
@@ -41,6 +41,42 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
   }
 
 
+  protected function _getErrorFromCode($code, $default_message) {
+    $error_messages = [
+                       'ageRestricted' => $this->_('limitation sur l\'âge'),
+                       'damaged' => $this->_('exemplaire endommagé'),
+                       'cannotReserveFromOtherBranches' => $this->_('réservation impossible dans cette bibliothèque'),
+                       'tooManyReserves' => $this->_('nombre maximum de réservations atteint'),
+                       'notReservable' => $this->_('ce document ne peut normalement pas être réservé'),
+                       'debarred' => $this->_('compte bloqué'),
+                       'expired' => $this->_('compte expiré'),
+                       'alreadyReserved' => $this->_('document déjà réservé sur votre compte'),
+                       'none_available' => $this->_('aucun document n\'est disponible pour la réservation'),
+                       'on_reserve' => $this->_('document réservé par un autre lecteur'),
+                       'too_many' => $this->_('nombre maximum de prolongations atteint'),
+                       'onsite_checkout' => $this->_('document en prêt sur place'),
+                       'restriction' => $this->_('limitation sur l\'âge'),
+                       'overdue' => $this->_('documents en retard'),
+                       'too_soon' => $this->_('trop tôt pour renouveler')
+    ];
+
+    return isset($error_messages[$code])
+      ? $default_message.' : '.$error_messages[$code]
+      : $default_message;
+  }
+
+
+  protected function _findErrorTagInXml($xml,$tag) {
+    if ($error = $this->_getTagData($xml, $tag))
+      return $error;
+
+    if ($success = $this->_getTagData($xml,'success'))
+      return 0 == $success;
+
+    return false !== strpos($xml, $tag) ;
+  }
+
+
   protected function _authenticateWebservice($user) {
     $xml_auth = $this->httpGet(['service' => 'AuthenticatePatron',
                                 'username' => $user->getLogin(),
@@ -141,7 +177,7 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
   public function prolongerPret($user, $pret_id) {
     return $this->ilsdiRenewLoan(['patron_id'  => $user->getIdSigb(),
                                   'item_id'    => $pret_id],
-                                 '(message|error)');
+                                 'error');
   }
 
 
diff --git a/library/Class/WebService/SIGB/Nanook/Service.php b/library/Class/WebService/SIGB/Nanook/Service.php
index 5e8b3096d6196e0b89b7ec0bc2a6db816a060639..56acf358b34842ef61426c14e354bd73172068e6 100644
--- a/library/Class/WebService/SIGB/Nanook/Service.php
+++ b/library/Class/WebService/SIGB/Nanook/Service.php
@@ -352,7 +352,7 @@ class Class_Webservice_SIGB_Nanook_Service extends Class_WebService_SIGB_Abstrac
   protected function _getErrorFromCode($error_code, $message) {
     if(array_key_exists($error_code, $this->_error_codes))
       $message = $this->_getErrorLabel($error_code);
-    return $this->_error($message);
+    return $message;
   }
 
 
diff --git a/tests/library/Class/WebService/SIGB/KohaTest.php b/tests/library/Class/WebService/SIGB/KohaTest.php
index 32ddda29a2d271af734bb2c9a2bf0730e99b17fb..6b578a8e9f228b650d2698d3f033955c0175b5b1 100644
--- a/tests/library/Class/WebService/SIGB/KohaTest.php
+++ b/tests/library/Class/WebService/SIGB/KohaTest.php
@@ -854,7 +854,7 @@ class KohaOperationsTest extends KohaTestCase {
                                 </RenewLoan>');
 
 
-    $this->assertEquals(array('statut' => false, 'erreur' => 'Prolongation impossible'),
+    $this->assertEquals(array('statut' => false, 'erreur' => 'Prolongation impossible : nombre maximum de prolongations atteint'),
                         $this->service->prolongerPret($this->_lafond, '24426'));
   }
 
@@ -944,6 +944,8 @@ class KohaOperationsTest extends KohaTestCase {
 
 
 
+
+
   /** @test */
   function reserverExemplaireShouldReturnErrorIfFail() {
     $this->mock_web_client
@@ -1102,7 +1104,7 @@ class KohaServicePatroninfoReaderWithNoLibTest extends KohaTestCase {
                       ->setLogin('lafond')
                       ->setPassword('afi')
                       ->setIdabon('012345'));
- }
+  }
 
 
   /** @test */
@@ -1186,4 +1188,94 @@ class KohaAuthenticateWSTest extends KohaTestCase {
   }
 
 
+}
+
+
+
+
+class KohaErrorMessagesOperationTest extends KohaTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->_lafond = $this->fixture('Class_Users',
+                                    ['id' => 67,
+                                     'login' => 'lafond',
+                                     'password' => 'afi',
+                                     'id_sigb' => '572',
+                                     'idabon' => '012345']);
+
+    $this->_exemplaire_mireille_abeille = $this->fixture('Class_Exemplaire',
+                                                         ['id' => 123,
+                                                          'id_origine' => '89863']);
+    Class_TextReplacements::reset();
+  }
+
+
+  public function tearDown() {
+    Class_TextReplacements::reset();
+    parent::tearDown();
+  }
+
+
+  public function getHoldTitleErrors() {
+    return [
+            ['ageRestricted' , 'limitation sur l\'âge'],
+            ['damaged' , 'exemplaire endommagé'],
+            ['cannotReserveFromOtherBranches' , 'réservation impossible dans cette bibliothèque'],
+            ['tooManyReserves' , 'nombre maximum de réservations atteint'],
+            ['notReservable' , 'ce document ne peut normalement pas être réservé'],
+            ['debarred' , 'compte bloqué'],
+            ['expired' , 'compte expiré'],
+            ['alreadyReserved' , 'document déjà réservé sur votre compte'],
+            ['none_available' , 'aucun document n\'est disponible pour la réservation']
+    ];
+  }
+
+
+  /**
+   * @dataProvider getHoldTitleErrors
+   * @test
+   */
+  public function holdTitleErrorsShouldBeAsExpected($code, $message) {
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with('http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl?service=HoldTitle&patron_id=572&bib_id=89863&request_location=127.0.0.1')
+      ->answers('<HoldTitle>
+                 <code>'.$code.'</code>
+                </HoldTitle>');
+
+    $this->assertEquals(array('statut' => false, 'erreur' => 'Réservation impossible : '.$message),
+                        $this->service->reserverExemplaire($this->_lafond, $this->_exemplaire_mireille_abeille, ''));
+  }
+
+
+  public function getRenewTitleErrors() {
+    return [
+            ['on_reserve' , 'document réservé par un autre lecteur'],
+            ['too_many' , 'nombre maximum de prolongations atteint'],
+            ['onsite_checkout' , 'document en prêt sur place'],
+            ['restriction' , 'limitation sur l\'âge'],
+            ['overdue' , 'documents en retard'],
+            ['too_soon' , 'trop tôt pour renouveler']
+    ];
+  }
+
+
+  /**
+   * @dataProvider getRenewTitleErrors
+   * @test
+   */
+  public function renewTitleErrorsShouldBeAsExpected($code, $message) {
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with('http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl?service=RenewLoan&patron_id=572&item_id=24426')
+      ->answers('<RenewLoan>
+                                   <success>0</success>
+                                   <renewals>1</renewals>
+                                   <error>'.$code.'</error>
+                                   <date_due>2009-06-22</date_due>
+                                </RenewLoan>');
+
+    $this->assertEquals(array('statut' => false, 'erreur' => 'Prolongation impossible : '.$message),
+                        $this->service->prolongerPret($this->_lafond, '24426'));
+  }
 }
\ No newline at end of file
diff --git a/tests/library/Class/WebService/SIGB/NanookTest.php b/tests/library/Class/WebService/SIGB/NanookTest.php
index 353842200898224b4966a9d330eace943748014e..fe09561ced361cf707b8feb24cf9ce8594bda785 100644
--- a/tests/library/Class/WebService/SIGB/NanookTest.php
+++ b/tests/library/Class/WebService/SIGB/NanookTest.php
@@ -100,6 +100,13 @@ abstract class NanookTestCase extends ModelTestCase {
                                           'id_bib' => 5,
                                           'id_origine' => 8]);
   }
+
+
+  public function tearDown() {
+    $this->_mock_web_client = null;
+    $this->_service = null;
+    parent::tearDown();
+  }
 }