mojolicious / mojo

:sparkles: Mojolicious - Perl real-time web framework

Home Page:https://mojolicious.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't locate object method "" via package "Mojolicious::Validator::Validation"

daleif opened this issue · comments

  • Mojolicious version: 9.35
  • Perl version: 5.34
  • Operating system: Ubuntu 22.04

Steps to reproduce the behavior

In this example I'm using a filter that is not defined (say a typo)

#!/usr/bin/env perl
use Mojolicious::Lite -signatures;

get '/' => sub ($c) {
  $c->render(template => 'index');
};
post '/' => sub ($c) {
    $c->validation->optional('test','foo');
    return $c->render(text => 'foo');
};
app->start;

__DATA__

@@ index.html.ep
% layout 'default';

<form action="/" method="POST">
    <input type="text" name="test" />
    <input type="submit" value="Submit" />
</form>

@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
  <head><title><%= title %></title></head>
  <body><%= content %></body>
</html>

Expected behavior

Ought to be some message in the log that the filter foo does not exist.

Actual behavior

Run under morbo or so and hit the button. This gives us the rather unuseful error

Use of uninitialized value $cb in method lookup at .../Mojolicious/Validator/Validation.pm line 74.
[2023-11-13 16:32:52.60911] [38589] [error] [mSTxzMBC76Is] Can't locate object method "" via package "Mojolicious::Validator::Validation" ...

It comes from this code

  for my $cb (map { $self->validator->filters->{$_} } @filters) {
      @input = map { $self->$cb($name, $_) } @input;
  }

The filters->{$_} part is returning undef of the filter is unknown to the list. And thus we pass on undef as a call back to be used inside the loop. Where it fails the code crashes.

Note sure what the best bethod would be here, but something like

      Carp::croak sprintf("Error in filter list for '%s', at least one of these does not exist: '%s'\n",$name,join(',',@filters)) 
            unless defined $cb;
      @input = map { $self->$cb($name, $_) } @input;

might at least help to debug something like this.