[Dancer-users] Input-validation and Error-Handling in a fun 'dancer' way

Octavian Rasnita orasnita at gmail.com
Wed Sep 14 21:55:47 CEST 2011


HTML::FormFu can verify very easy if the submitted form would create a dupplicate in the database, using a custom Validator.

Such a validator could look like the one below.
I created it under the HTML::FormFu namespace, but it can be created under application's namespace

It is done for a Catalyst-based app, so the line:
  my $c = $self->form->stash->{context};
just gets the context object $c from the form's stash, because it needs to access the DBIC model that searches in the database if the value of the field ($value, which is also found in the $fields hashref) is unique in the database.
The DBIC method unique_community_name just searches if it is unique, and it returns just true/false.

And the HTML::FormFu may print a custom message defined with the key "message" for this Validator, so it is all very clean, and you may use the unique_community_name method to do the searches for uniqueness for other things, and you may also use this validator for other forms.
(Too tired right now, so my explanations might not be very clear:)


package HTML::FormFu::Validator::BRK::UniqueCommunityNameAdd;

use strict;
use warnings;
use parent 'HTML::FormFu::Validator';

sub validate_value {
  my ($self, $value, $params) = @_;
  my $c = $self->form->stash->{context};
  return $c->model("DB::Usr")->unique_community_name_add($params);
}

1;


Octavian

----- Original Message ----- 
From: "Brian E. Lozier" <brian at massassi.com>
To: "Assaf Gordon" <gordon at cshl.edu>
Cc: <dancer-users at perldancer.org>
Sent: Wednesday, September 14, 2011 9:22 PM
Subject: Re: [Dancer-users] Input-validation and Error-Handling in a fun 'dancer' way


> On Wed, Sep 14, 2011 at 11:12 AM, Assaf Gordon <gordon at cshl.edu> wrote:
> 
>> Hello Dancers,
>>
>> I have another dancer-newbie question:
>>
>> Is there a recommended way to verify input (or general variables) and
>> report errors to the user ?
>>
> 
> Hello,
> 
> I use a combination of HTML::FormFu and Dancer::Plugin::FlashMessage for
> this purpose.  HTML::FormFu has built-in ways to validate data and report
> input errors back to the user.  This isn't quite enough because even though
> the input can be perfectly valid, there are times when something during form
> processing will fail (for example, a database duplicate key). In those cases
> I use the FlashMessage to report it to the user.  There are numerous
> advantages to using HTML::FormFu or some other form handling library.
> First, they provide a framework for doing form validation so you don't have
> to manually code it for each form. Second, they provide a way to
> structure/define your forms so they can be reused (or inherited from) in
> other places.  Third, they provide feedback for invalid fields right by the
> fields.  Fourth, they leverage a ton of work that other developers have put
> into solving the same problem.  There are countless more.
> 
> No, HTML::FormFu isn't perfect but I've found it to be a time saver in the
> long run, even after just a couple of forms.
> 
> What I do is define the route to accept GET and POST.  Then I create an
> HTML::FormFu object.  I use the HTML::FormFu mechanism for detecting whether
> the form was submitted.  If the form was submitted and is valid, I process
> it and redirect the user to a confirmation page (with a friendly message).
> If the form was not submitted or was not valid, I just return the template,
> passing the form object in for rendering.  HTML::FormFu takes care of
> outputting the raw form or possibly with error messages interpolated if the
> input was invalid.
> 
> 
>>
>> Common scenario:
>> I have a form with 3 inputs, and they need to by in a certain format
>> (verifiable by a simple regex).
>> If the inputs do not conform, I want to:
>>
>> 1. Log the error for later inspection
>> 2. Inform the user (e.g. using Plugin::Dancer::FlashMessage)
>> (The error message reported to the user is not necessarily the same one
>> written to the log, if I wish to include more technical details in the log,
>> or be more descriptive and verbose to the user).
>> 3. Stop processing the request.
>>
>> And I wish to do it in the most 'fun' dancer kind of way.
>>
>> Looking at a naive implementation (below), there's alot of redundant code
>> for validating and reporting the error back to the user (and more validation
>> code than actual processing code).
>>
>> Any suggestions ?
>>
>> Thanks!
>>  -gordon
>>
>>
>> ====================
>>
>> post '/dosomething' => sub {
>>    my $email = params->{email};
>>    my $gene = params->{gene};
>>    my $cutoff = param->{cutoff};
>>
>>     if (!defined $email) {
>>        warning "Missing email address";
>>        flash error => 'Missing email address';
>>        return template 'form_errors' ;
>>    }
>>    elsif (!valid_email($email)) {
>>        warning "Got Invalid email address: $email";
>>        flash error => 'Invalid email address";
>>        return template 'form_errors' ;
>>    }
>>
>>    if (!defined $gene) {
>>        warning "Missing gene identifier";
>>        flash error => 'Missing gene identifier';
>>        return template 'form_errors' ;
>>    }
>>    elsif (!valid_gene_identifier($gene)) {
>>        warning "Got Invalid gene identifier: $gene";
>>        flash error => 'Invalid gene identifier";
>>        return template 'form_errors' ;
>>    }
>>
>>    if (!defined $cutoff) {
>>        warning "Missing cutoff identifier";
>>        flash error => 'Missing cutoff identifier';
>>        return template 'form_errors' ;
>>    }
>>    elsif (!valid_cutoff_value($cutoff)) {
>>        warning "Got Invalid cutoff value: $cutoff";
>>        flash error => 'Invalid Cutoff value: must a value between 0.1 and
>> 0.55';
>>        return template 'form_errors' ;
>>    }
>>
>>    ## Input IS OK, do some processing and return the result
>>    my ($result, $error) = process($email, $gene, $cutoff);
>>
>>    template 'result.tt', {
>>          email => $email,
>>          cutoff => $cutoff,
>>          gene  => $gene,
>>          result => $result,
>>          error => $error,
>>    };
>> }
>> _______________________________________________
>> Dancer-users mailing list
>> Dancer-users at perldancer.org
>> http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
>>
>


--------------------------------------------------------------------------------


> _______________________________________________
> Dancer-users mailing list
> Dancer-users at perldancer.org
> http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
>


More information about the Dancer-users mailing list