Özel durum Mesajlar: En iyi uygulamalar

5 Cevap php

Ben özel durum iletilerini oluştururken yararlı hata ayıklama bilgileri zorlamak için ne kadar çaba gitmeli merak, ya da sadece doğru bilgi sağlamak veya bir istisna işleyicisi toplama bilgileri erteleme kullanıcıyı güvenmeliyiz?

Ben gibi onların durumları yapan insanlar bir sürü insan görürsünüz:

throw new RuntimeException('MyObject is not an array')

veya çok yapmak ancak istisna adını değiştirmeyin özel istisnalar dışında varsayılan istisnalar uzanan:

throw new WrongTypeException('MyObject is not an array')

Ama bu ... çok hata ayıklama bilgi kaynağı değildir ve hata mesajı ile biçimlendirme her türlü zorlamaz. Yani tam olarak aynı hata iki farklı hata iletileri üretme ile bitebileceğini ... örn vs "Veritabanı bağlantısı başarısız oldu" "db bağlanamıyor"

Tabii, üst kabarcıklar, eğer yararlı olduğu, yığın izleme basalım, ama her zaman keşfetmek için) bana ifadeleri bilmek gerekiyor ve genellikle ben (var_dump kapalı çekim başlamak zorunda sona her şeyi söylemek değil ne bu biraz iyi bir istisna işleyicisi ile telafi edilebilir ama ... yanlış ve nerede gitti.

Ben istisna require atıcı doğru hata mesajı üretmek için gerekli argümanlarımdan sağlamak için aşağıdaki kodu gibi bir şey, düşünmeye başlıyorum. Ben bu o gitmek için yol olabilir düşünüyorum:

  • Yararlı bilgi minimum düzeyde sağlanmalıdır
  • Biraz tutarlı hata iletileri üretir
  • Istisna mesajları için kalıplar bir konum (istisna sınıfları), daha kolay mesajları güncellemek için böylece tüm ...

Ama (eğer istisna tanımı bakmak gerekir), ve dolayısıyla sağlanan istisnalar kullanarak diğer programcılar vazgeçirmek olabilir olumsuz da kullanmak zor olduğu varlık görmek ...

Ben bu fikri bazı yorum istiyorum, ve istiyorum tutarlı, esnek bir istisna mesajı çerçevesi için en iyi uygulamaları.

/**
* @package MyExceptions
* MyWrongTypeException occurs when an object or 
* datastructure is of the incorrect datatype.
* Program defensively!
* @param $objectName string name of object, eg "\$myObject"
* @param $object object object of the wrong type
* @param $expect string expected type of object eg 'integer'
* @param $message any additional human readable info.
* @param $code error code.
* @return Informative exception error message.
* @author secoif
*/
class MyWrongTypeException extends RuntimeException {
    public function __construct($objectName, $object, $expected, $message = '', $code = 0) {
        $receivedType = gettype($object) 
        $message = "Wrong Type: $objectName. Expected $expected, received $receivedType";
        debug_dump($message, $object);
        return parent::__construct($message, $code);
    }
}

....

/**
 * If we are in debug mode, append the var_dump of $object to $message
 */
function debug_dump(&$message, &$object) {
     if (App::get_mode() == 'debug') {
         ob_start();
         var_dump($object);
         $message = $message . "Debug Info: " . ob_get_clean();
    }
}

Sonra eskisi gibi:

// Hypothetical, supposed to return an array of user objects
$users = get_users(); // but instead returns the string 'bad'
// Ideally the $users model object would provide a validate() but for the sake
// of the example
if (is_array($users)) {
  throw new MyWrongTypeException('$users', $users, 'array')
  // returns 
  //"Wrong Type: $users. Expected array, received string
}

ve biz html çıkışı için güzel şeyler yapmak için bir özel durum işleyici bir nl2br gibi bir şey yapmak gerekebilir.

Been reading: http://msdn.microsoft.com/en-us/library/cc511859.aspx#

Ve orada böyle bir şey hiç bahsedilmemesi, bu yüzden belki de kötü bir fikir ...

5 Cevap

Ben kuvvetle Krzysztof's blog üzerine tavsiye tavsiye ve sizin durumunuzda o Kullanımı Hatalar dediği ile başa çıkmak için çalışıyor gibi görünüyor dikkat cekti.

Bu durumda ne gerekli onu göstermek için yeni bir tip ama sebep ne hakkında daha iyi bir hata mesajı değildir. Ya da bu tür bir yardımcı işlev gibi:

  1. istisna içine yerleştirmek için metinsel dize oluşturmak
  2. bütün durum ve mesaj oluşturmak

Gerekli olan budur.

Yaklaşım 1 nettir, ama biraz daha ayrıntılı kullanımı, 2 daha az netlik için bir terser sözdizimi, ticaret tersidir yol açabilir.

Fonksiyonları (onlar, hiç alakasız bir istisna kendilerini neden asla) son derece güvenli olması ve bazı makul kullanımlarda isteğe bağlı veri sağlanmasını zorlamamak gerektiğini unutmayın.

Bu yaklaşımlardan birini kullanarak gerekirse daha kolay daha sonra hata mesajı uluslar yapmak.

En azından bir yığın izlemesi böylece o dışarı çalışmak kolay değil bilgi temin odaklanmalıdır size işlevi, ve muhtemelen satır sayısını verir.

Krzysztof Cwalina, "Çerçeve Tasarım Rehberi" bir yazarlarından bir blogda How to Design Exception Hierarchies bakın.

Asla, hiç 'doğru şeyi yapmak' için bir kullanıcı güven ve hata ayıklama bilgileri içerir. Eğer bilgi istiyorsanız, bunu kendiniz toplamak ve bir yere nerede onun erişilebilir saklamak gerekir.

Bir şey yapmak için (er) sabit olmadığını ifade aynı zamanda, kullanıcıların böylece yine, onların iyi niyet ve göndermek için gereken ne kendi bilgisine bağlı değildir, bunu yaparken önlemek olacaktır.

Bu düşünce bir yere) (var_dump kullanarak ima, bilgi toplamak ve bunu log hangi bir yöntemi ifade eder.

Ayrıca, Mark Harrison, kolay bir yerde bir hata mesajı göndermek için yapar, bir düğme tarafından dedi sizin için ve kullanıcılar için harika. Bu kolay onları bir hata bildirmek için yapar. Sen (alıcı olarak) çiftleri bir şey olsun, ama yinelenen bilgiler hiçbir bilgi daha iyidir.

Eklemek Ancak çok detay, ya emin olun ve

  • kesilmiş ve her şeyi yapıştırmak için kolay yapmak, ya da
  • onlar için hata rapor edecek bir düğme var

Ben Pastör'e günlüğü ile ilgili tavsiye olumsuz etkisi olmaz, ama burada özel durumlar oluşturmak için bir ölü kolay bir yoludur.

Örnek:

<?php
   require_once "CustomException.php";
   class SqlProxyException extends CustomException {}

   throw new SqlProxyException($errorMsg, mysql_errno());     
?>

Bunun ardındaki kodu (yerde ödünç, özür kimle olmasıydı)

<?php

interface IException
{
    /* Protected methods inherited from Exception class */
    public function getMessage();                 // Exception message
    public function getCode();                    // User-defined Exception code
    public function getFile();                    // Source filename
    public function getLine();                    // Source line
    public function getTrace();                   // An array of the backtrace()
    public function getTraceAsString();           // Formated string of trace

    /* Overrideable methods inherited from Exception class */
    public function __toString();                 // formated string for display
    public function __construct($message = null, $code = 0);
}

abstract class CustomException extends Exception implements IException
{
    protected $message = 'Unknown exception';     // Exception message
    private   $string;                            // Unknown
    protected $code    = 0;                       // User-defined exception code
    protected $file;                              // Source filename of exception
    protected $line;                              // Source line of exception
    private   $trace;                             // Unknown

    public function __construct($message = null, $code = 0)
    {
        if (!$message) {
            throw new $this('Unknown '. get_class($this));
        }
        parent::__construct($message, $code);
    }

    public function __toString()
    {
        return get_class($this) . " '{$this->message}' in {$this->file}({$this->line})\n"
                                . "{$this->getTraceAsString()}";
    }
}