Why does this attempt to customize a type constraint error message fail? - perl

The following construct creates a type constraint that functions as expected (checks for the "Roles::Thing" role when an attribute is set) When an attribute is rejected due to not passing the constraint I would expect the custom error message "Not a thing" to appear; however the default error message is still being given. What am I doing wrong?
role_type 'DoesThing', {
role => 'Roles::Thing',
message => sub { "Not a thing." }
};
Update: I did not provide enough context in the original post. The way I am trying to use the new type is:
has things => (
isa => 'ArrayRef[DoesThing]'
);
The type validation does work as expected; however I still get the default error message. My custom "Not a thing" error message is not propagated as I would have expected it to be.

The error message is what you get for an ArrayRef type, regardless of what you're expecting inside it.
To get a custom error message you'll need to incorporate ArrayRef into your type declaration:
subtype 'ArrayOfThings',
as 'ArrayRef[Roles::Thing]',
message { 'Not an array of things' };

Related

Optional on response FieldDescriptor not working as expected

I'm having trouble documenting optional response fields with Spring Docs.
My test code:
mockMvc.perform(get("/foo").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("foo", responseFields(
fieldWithPath("success").description("Indicates request successful or not."),
fieldWithPath("message").description("Message.").optional()
)));
My response:
{
"success" : true
}
The error:
org.springframework.restdocs.payload.FieldTypeRequiredException:
Cannot determine the type of the field 'message' as it is not present
in the payload. Please provide a type using
FieldDescriptor.type(Object type).
Spring REST Docs documentation states (https://docs.spring.io/spring-restdocs/docs/2.0.5.RELEASE/reference/html5/#documenting-your-api-request-response-payloads-fields)
Similarly, the test also fails if a documented field is not found in
the payload and the field has not been marked as optional.
So what am I doing wrong?
While the message field is marked as optional, REST Docs still wants to document it for you. Part of that documentation is the field's type. The field's missing from the response so REST Docs can't guess it automatically. Instead, you need to tell it using the type method:
fieldWithPath("message").description("Message.").optional().type(JsonFieldType.STRING)

Why afBedSheet don't see my types?

I'm running a BedSheet application but when I make a HTTP request to a particular route, I get this error in the browser
500 - Internal Server Error
afBeanUtils::TypeNotFoundErr
- Could not find match for Type mypod::MyClass.
Available Values
afBedSheet::FileAsset
afBedSheet::HttpStatus
afBedSheet::MethodCall
afBedSheet::Redirect
afBedSheet::Text
sys::File
sys::InStream
afBeanUtils::TypeNotFoundErr : Could not find match for Type mypod::MyClass.
afBeanUtils::TypeLookup.check (TypeLookup.fan:157)
afBeanUtils::TypeLookup.doFindParent (TypeLookup.fan:140)
However MyClass is there and it is being instantiated by other class. Why is not found?
That Err msg could be a little more informative...
It sounds like your request handler is returning an instance of mypod::MyClass and BedSheet is complaining that it doesn't know what to do with it.
You probably want to be returning an instance of afBedSheet::Text as in:
Obj indexPage() {
return Text.fromHtml("<html>Hello!</html>")
}
If the above doesn't sound right, then I'd need to see some code to be of further help.

Chaining Error Messages in Zend Framework

It seems that using addErrorMessage() overrides all other validation errors.
For example, I created a custom phone element. And I also created a custom validation class that checks for a custom business rule.
I expected it to print out the error messages from My_Validate_BusinessPhone when it did not meet the custom business rule. But it prints message set in addErrorMessage() all the time. Is this the normal behavior? Is there a way to chain the error messages?
$phone = new My_Form_Element_Phone( 'phone' );
$phone->setRequired( TRUE )
->setAttrib( 'id', 'phone' )
->addErrorMessage( 'Please provide a valid phone number' )
->addValidator( new My_Validate_BusinessPhone );
I thank you in advance.
The messages are overwritten, because you are setting the message to the form element and not to the validator. So that's how it should work: First, get your form element. In your case, just use it. Second, get the validator by name (I don't know how it's exacly called here, e.g. it could be 'notEmpty') and third, add your message for this validator.
$phone->getValidator('yourValidatorsName')->setMessage('Please provide a valid phone number');
I've just tested this in my own script, but I hope it should work ;-)

Zend Validate, Display one message per validator

I am validating an email address using zend_validate_email.
For example, for email address aa#aa it throws several error messages including very technical describing that DNS mismatch (:S).
I am trying to make it display only 1 message that I want it to (for example: "Please enter a valid email").
Is there any way of doing it elegantly, apart from creating a subclass and overriding the isValid method, clearing out the array of error messages?
Thanks!
$validator = new Zend_Validate_EmailAddress();
// sets the message for all error types
$validator->setMessage('Please enter a valid email');
// sets the message for the INVALID_SEGMENT error
$validator->setMessage('Something with the part after the # is wrong', Zend_Validate_EmailAddress::INVALID_SEGMENT);
For a full list of errors and message templates see the Zend_Validate_EmailAddress class

Zend_Validate_Abstract custom validator not displaying correct error messages

I have two text fields in a form that I need to make sure neither have empty values nor contain the same string.
The custom validator that I wrote extends Zend_Validate_Abstract and works correctly in that it passes back the correct error messages. In this case either: isEmpty or isMatch.
However, the documentation says to use addErrorMessages to define the correct error messages to be displayed.
in this case, i have attached
->addErrorMessages(array("isEmpty"=>"foo", "isMatch"=>"bar"));
to the form field.
According to everything I've read, if I return "isEmpty" from isValid(), my error message should read "foo" and if i return "isMatch" then it should read "bar".
This is not the case I'm running into though. If I return false from is valid, no matter what i set $this->_error() to be, my error message displays "foo", or whatever I have at index[0] of the error messages array.
If I don't define errorMessages, then I just get the error code I passed back for the display and I get the proper one, depending on what I passed back.
How do I catch the error code and display the correct error message in my form?
The fix I have implemented, until I figure it out properly, is to pass back the full message as the errorcode from the custom validator. This will work in this instance, but the error message is specific to this page and doesn't really allow for re-use of code.
Things I have already tried:
I have already tried validator chaining so that my custom validator only checks for matches:
->setRequired("true")
->addValidator("NotEmpty")
->addErrorMessage("URL May Not Be Empty")
->addValidator([*customValidator]*)
->addErrorMessage("X and Y urls may not be the same")
But again, if either throws an error, the last error message to be set displays, regardless of what the error truly is.
I'm not entirely sure where to go from here.
Any suggestions?
I think you misinterpreted the manual. It says
addErrorMessage($message): add an
error message to display on form
validation errors. You may call this
more than once, and new messages are
appended to the stack.
addErrorMessages(array $messages): add
multiple error messages to display on
form validation errors.
These functions add custom error messages to the whole form stack.
If you want to display validation error messages when the validation fails, you have to implement the message inside your validator.
ie.
const EMPTY = 'empty';
protected $_messageTemplates = array(
self::EMPTY => "Value is required and can't be empty",
);
public function isValid($value)
{
if(empty($value)) {
$this->_error(self::EMPTY);
return false;
}
return true;
}
This way, after the validation fails, you can get the error codes using $validator->getErrors() and the error messages using $validator->getMessages().
If you have the $_messageTemplates properly defined, Zend_Form automatically uses the error messages instead of error codes and prints them out.
Hope this helps.