Подтвердить что ты не робот

Как я могу получить структурированные исключения из Moose?

Рассмотрим этот простой класс:

package Foo;
use Moose;
has foo => ( is => 'rw', isa => 'Int' );

И затем этот код:

use Try::Tiny;
use Foo;
my $f = try {
    Foo->new( foo => 'Not an Int' );
}
catch {
    warn $_;
};

Код умирает с приятным большим сообщением об отсутствии ограничений типа.

Я хотел бы иметь возможность извлечь какой атрибут не удалось (foo), какая причина была (ограничение ограничения типа) и то, что переданное значение было (Not an Int), без необходимости синтаксического анализа строки ошибки, чтобы получить информация.

Что-то вроде этого:

catch {
    if( $_->isa( 'MooseX::Exception::TypeConstraint' ) ) {
         my $attrib = $_->attribute;
         my $type   = $_->type;
         my $value  = $_->bad_value;

         warn "'$value' is an illegal value for '$attrib'.  It should be a $type\n"; 
    }
    else {
         warn $_;
    }
};

Возможно ли это? Есть ли рассылка MooseX, которая может это сделать? Еще лучше, есть ли какая-то функция Moose, которую я пропустил, это сделает это возможным?

Обновление: Меня особенно интересуют ограничения типа, но другие ошибки Moose также будут очень хорошими. Я также знаю, что я могу сбрасывать объекты с помощью die. Таким образом, структурирование исключений в коде я записывается относительно просто.

4b9b3361

Ответ 1

Я не пробовал это сам, но я думаю, MooseX::Error::Exception::Class может быть тем, что вы ищете.

Ответ 2

Отметьте MooseX::Throwable, который заменяет значение error_class в метаклассе. Однако код выглядит немного старым (метаролы теперь поддерживают роли класса ошибок), но текущий метод выглядит так, как будто он все равно будет работать.

Ответ 3

У меня был такой же вопрос около года назад, и я спросил на #moose IRC-канале. Ответ состоял в том, что Moose действительно не поддерживает структурированные исключения... еще.

Существует общее согласие, что это недостаток Moose, который должен быть исправлен, но задача введения исключений повсюду утомительна и еще не выполнена (afaik).

Подход в MooseX:: Error:: Exception:: Class очень хрупкий, поскольку он основан на разборе сообщений из Moose.

Поскольку вы не можете действительно получить надежные структурированные исключения из Moose, подумайте об использовании интроспекции для проверки каждого из ваших ограничений типа один за другим при установке нового значения. Иногда это приемлемый подход.

Btw: обратите внимание, что существует неприятная ошибка в том, как Moose обрабатывает составные ограничения.