2012-07-20 25 views
8

this'a çok benzer bir şey yapmak istiyorum ama AJAX istekleri için CakePHP dünyasında. Şu anda bunu yapıyorum:CakePHP'de Ajax hata yönetimi

$this->autoRender = false; 
$this->response->statusCode(500); 

O this off dayanır. Ancak bu çözüm, Rails örneğinde olduğu gibi özel bir mesaj eklememe izin vermiyor, bu şekilde, müşterilerim yan hata işleyicisinde, 500 hata yanıtında yer alan mesajı görüntüleyebilirim.

CakePHP'de Ruby on Rails örneğinde olduğu gibi aynı işlevselliği nasıl uygularım?

cevap

0
Cookbook'ta açıklandığı gibi CakeExceptions kullanabilirsiniz

: Eğer özel mesajları kullanmak istiyorsanız üretim modunda :(içinde debug = 1 kullanmaktan daha başka bir yol bulduk http://book.cakephp.org/2.0/en/development/exceptions.htmlANCAK

yerleşik İşte benim yaklaşım yöntemler: kumandanızda olarak

:

if($this->request->is('ajax')){ 
    Configure::write('debug', 1); 
} 

if(!$allowed) { 
    throw new InternalErrorException('Keep your fingers away from me!'); // 500 error 
} 

Değişim AJAX kullanılan hata ama çıkış hiçbir şey hata şablonu /app/View/Errors/error500.ctp:

<?php 
if($this->request->is('ajax')): 
    // Output for AJAX calls 
    echo $name; 

else: 
    //Standard CakePHP output ?> 
    <h2><?php echo $name; ?></h2> 
    <p class="error"> 
     <strong><?php echo __d('cake', 'Error'); ?>: </strong> 
     <?php echo __d('cake', 'An Internal Error Has Occurred.'); ?> 
    </p> 
    <?php 
    if (Configure::read('debug') > 0): 
     echo $this->element('exception_stack_trace'); 
    endif; 

endif; ?> 

yılında Ardından AJAX döndürülen metni ayrıştırabilir çağırır.

//... 
error: function (request) { 
    yourErrorShowingFunction(_this, request.responseText); 
} 
//... 

Umut bu yardımcı olur :) Herkes nasıl (hata ayıklama modu üzerine yazmadan) üretim modunda özel hatalarını kullanmak için bir fikir varsa

olacağım: İşte jQuery parçalarını kullandığım var çok mutlu!

+0

Bu, hata ayıklama modunda olmasını içerdiğinden umuyordum, bununla ilgili hiçbir fikrim yok gibi göründüğü için bunu doğru olarak işaretleyeceğim. Çaba için teşekkürler! –

2

Ayrıca ajax istekleri kullanırken (benim durumumda jquery mobile) özel istisnalar ve hata kodları ile uğraştım. İşte, hata ayıklama modunun üzerine yazmadan dahil olduğum çözüm. Geliştirme modunda ve ayrıca isteğe bağlı olarak üretim modunda özel hatalar atar.

AppExceptionRenderer.php: Eğer hata ayıklama modunda istisna görüntülemek istiyorsanız

<?php 
App::uses('ExceptionRenderer', 'Error'); 

class AppExceptionRenderer extends ExceptionRenderer 
{ 
    public function test($error) 
    { 
     $this->_sendAjaxError($error); 
    } 

    private function _sendAjaxError($error) 
    { 
     //only allow ajax requests and only send response if debug is on 
     if ($this->controller->request->is('ajax') && Configure::read('debug') > 0) 
     { 
      $this->controller->response->statusCode(500); 
      $response['errorCode'] = $error->getCode(); 
      $response['errorMessage'] = $error->getMessage(); 
      $this->controller->set(compact('response')); 
      $this->controller->layout = false; 
      $this->_outputMessage('errorjson'); 
     } 
    } 
} 

Sen Configure::read('debug') > 0 dışarı bırakabilir bunu birileri yardımcı olur. errorjson.ctp görünümü 'Error/errorjson'da bulunur.ctp ': Bu durumda

<?php 
echo json_encode($response); 
?> 

benim istisna denir

TestException

ve olarak tanımlanır aşağıdaki gibidir: Ben özel bir hata kodu var

<?php 
class TestException extends CakeException { 
    protected $_messageTemplate = 'Seems that %s is missing.'; 

    public function __construct($message = null, $code = 2) { 
     if (empty($message)) { 
        $message = 'My custom exception.'; 
      } 
      parent::__construct($message, $code); 
    } 
} 

Benim json cevabı için 2, $code = 2. ajax yanıtı şu json verilerle bir hata 500 kullanacaklar:

{"errorCode":"2","errorMessage":"My custom exception."} 

Açıkçası, ayrıca denetleyicisinden istisna gerekir:

throw new TestException(); 

ve istisna renderer dahil http://book.cakephp.org/2.0/en/development/exceptions.html#using-a-custom-renderer-with-exception-renderer-to-handle-application-exceptions

Bu biraz kapsam dışı olabilir, ancak JQuery'de ajax hata yanıtını işlemek için kullanıyorum:

$(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) { 
    //deal with my json error 
}); 
+0

Çok iyi çalışıyor. Teşekkürler. – MotsManish

7

Yukarıda belirtildiği gibi, Özel Durumlar, CakePHP'deki bir AJAX isteğinde bir hata döndürmenin yoludur. İşte hatanın neye benzediğini daha iyi kontrol etmek için benim çözümüm. Ayrıca, yukarıdaki gibi, özel bir Özel Durum Oluşturucu kullanıyorum, ancak özel bir istisna kullanmıyorum. Varsayılan hata yanıtı bir JSON böyle nesnesidir: varsayılan oluşturucu AJAX işlediğine dikkat yolu gibi

{"name":"An Internal Error Has Occurred", "url": "\/users\/login.json"} 

Ben neredeyse; bootstrap.php içinde,

<?php 
// File: /app/Lib/Error/CustomExceptionRenderer.php 
App::uses('ExceptionRenderer', 'Error'); 
class CustomExceptionRenderer extends ExceptionRenderer { 

    // override 
    public function error400($error) { 
     $this->_prepareView($error, 'Not Found'); 
     $this->controller->response->statusCode($error->getCode()); 

     $this->_outputMessage('error400'); 
    } 

    // override 
    public function error500($error) { 
     $this->_prepareView($error, 'An Internal Error Has Ocurred.'); 
     $code = ($error->getCode() > 500 && $error->getCode() < 506) ? $error->getCode() : 500; 
     $this->controller->response->statusCode($code); 

     $this->_outputMessage('error500'); 
    } 

    private function _prepareView($error, $genericMessage) { 
     $message = $error->getMessage(); 
     if(!Configure::read('debug') && !Configure::read('detailed_exceptions')) { 
      $message = __d('cake', $genericMessage); 
     } 
     $url = $this->controller->request->here(); 
     $renderVars = array(
      'name' => h($message), 
      'url' => h($url), 
      ); 
     if(isset($this->controller->viewVars['csrf_token'])) { 
      $renderVars['csrf_token'] = $this->controller->viewVars['csrf_token']; 
     } 
     $renderVars['_serialize'] = array_keys($renderVars); 
     $this->controller->set($renderVars); 
    } 
} 

Sonra: Sadece bunu biraz oynamak istiyorum

  • Yeni dönmek istiyorum ki: Yani burada

    Configure::write('Exception.renderer', 'CustomExceptionRenderer'); 
    

    nasıl işliyor Hata yanıtımdaki CSRF belirteci, böylece mevcut belirtecimin istisnası atılmadan önce geçerliliğini yitirmiş olsaydım, isteğimi bir daha denediğimde karanlığa kapılmam. CSRF koruması hakkında daha fazla bilgi için Security Component documentation'a bakın.

  • App/Lib/Error'da yeni bir sınıf oluşturun. Varsayılan oluşturucuyu genişletebilir veya genişletemezsiniz. Sadece birkaç küçük şeyi değiştirmek ve örneği basit tutmak istediğim için genişletiyorum.
  • Varsayılan oluşturucunun döndürülen JSON nesnesini oluşturmak için kullandığı yöntemleri geçersiz kılın. Bu, Request Handler Component aracılığıyla yapılır ve en iyi uygulamalara uygundur. Gerçekten, varsayılan oluşturucu aynı şeyi yapar.
  • İşleri devam ettirmek için yeni özel yöntem DRY.
  • Üretimde özel hata iletileri almama sorununa çözümüm, isteğe bağlı bir yapılandırma anahtarı eklemektir. Varsayılan olarak bu sınıf, üretimdeki genel iletileri gösterecektir, ancak hata ayıklamasının 0 olarak ayarlandığını ve belirli hata iletilerini istiyorsanız: Configure::write('detailed_exceptions', 1);
  • Varsa, yeni belirteci yanıtla ekleyin.Benim durumumda, daha önceadresinde bulunan AppController'ın beforeFilter yönteminde yeni belirtecin üzerinde Controller::set'u aradım. Bunu başarmak için muhtemelen onlarca başka yol var.

Şimdi yanıtı şöyle:

{ 
    "name":"The request has been black-holed", 
    "url":"\/users\/login.json", 
    "csrf_token":"1279f22f9148b6ff30467abaa06d83491c38e940" 
} 

Herhangi ek verileri, herhangi bir türü aynı sonuç için Controller::set geçirilen diziye eklenebilir.

+0

bu gerçekten bana çok yardımcı oluyor. –