diff options
author | Yorhel <git@yorhel.nl> | 2021-01-10 13:12:03 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2021-01-10 13:12:05 +0100 |
commit | 34c8fdd405021af24f66fd1301902b6ae03d1d02 (patch) | |
tree | 0ad5c164a8f4387899d067ed95246bbdeab8cde3 /lib | |
parent | bc87360592b827abd454b3c2fc9697ceb66e0148 (diff) |
AdvSearch: Improve error reporting when query validation failed
Amazing how can browsers(?) and bots mangle URLs sometimes.
Anyway, the user will now get a friendly error message instead of a 500,
and I get to see log messages. Everyone happy. I hope.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VNWeb/AdvSearch.pm | 25 | ||||
-rw-r--r-- | lib/VNWeb/Releases/List.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/TT/TagPage.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/VN/List.pm | 2 |
4 files changed, 25 insertions, 6 deletions
diff --git a/lib/VNWeb/AdvSearch.pm b/lib/VNWeb/AdvSearch.pm index 66b45172..cc4ea6a2 100644 --- a/lib/VNWeb/AdvSearch.pm +++ b/lib/VNWeb/AdvSearch.pm @@ -500,8 +500,8 @@ sub _validate { } -# 'advsearch' validation, accepts either a compact encoded string, JSON string or an already decoded array. -TUWF::set('custom_validations')->{advsearch} = sub { my($t) = @_; +{ required => 0, type => 'any', default => bless({type=>$t}, __PACKAGE__), func => sub { +sub _validate_adv { + my $t = shift; return { msg => 'Invalid JSON', error => $@ =~ s{[\s\r\n]* at /[^ ]+ line.*$}{}smr } if !ref $_[0] && $_[0] =~ /^\[/ && !eval { $_[0] = JSON::XS->new->decode($_[0]); 1 }; if(!ref $_[0]) { my($v,$i) = ($_[0],0); @@ -511,8 +511,25 @@ TUWF::set('custom_validations')->{advsearch} = sub { my($t) = @_; +{ required => my $v = _validate($t, @_); $_[0] = bless { type => $t, query => $_[0] }, __PACKAGE__ if $v; $v -} } }; +} + +# 'advsearch' validation, accepts either a compact encoded string, JSON string or an already decoded array. +TUWF::set('custom_validations')->{advsearch} = sub { my($t) = @_; +{ required => 0, type => 'any', default => bless({type=>$t}, __PACKAGE__), func => sub { _validate_adv $t, @_ } } }; + +# 'advsearch_err' validation; Same as the 'advsearch' validation except it never throws an error. +# If the validation failed, this will log a warning and return an empty query that will cause elm_() to display a warning message. +TUWF::set('custom_validations')->{advsearch_err} = sub { + my ($t) = @_; + +{ required => 0, type => 'any', default => bless({type=>$t}, __PACKAGE__), func => sub { + my $r = _validate_adv $t, @_; + if(!$r || ref $r eq 'HASH') { + warn "advsearch validation failed\n"; + $_[0] = bless {type=>$t,error=>1}, __PACKAGE__; + } + 1 + } } +}; # "Canonicalize"/simplify a query (in Normalized JSON form): @@ -723,6 +740,7 @@ sub elm_ { labels => { aoh => { id => { uint => 1 }, label => {} } }, defaultSpoil => { uint => 1 }, saved => { aoh => { name => {}, query => {} } }, + error => { anybool => 1 }, query => $VNWeb::Elm::apis{AdvSearchQuery}[0], }}); VNWeb::HTML::elm_ 'AdvSearch.Main', $schema, { @@ -730,6 +748,7 @@ sub elm_ { labels => auth ? tuwf->dbAlli('SELECT id, label FROM ulist_labels WHERE uid =', \auth->uid, 'ORDER BY CASE WHEN id < 10 THEN id ELSE 10 END, label') : [], defaultSpoil => auth->pref('spoilers')||0, saved => auth ? tuwf->dbAlli('SELECT name, query FROM saved_queries WHERE uid =', \auth->uid, ' AND qtype =', \$self->{type}, 'ORDER BY name') : [], + error => $self->{error}?1:0, query => $self->elm_search_query(), }; } diff --git a/lib/VNWeb/Releases/List.pm b/lib/VNWeb/Releases/List.pm index 4f3664ca..723f70f0 100644 --- a/lib/VNWeb/Releases/List.pm +++ b/lib/VNWeb/Releases/List.pm @@ -34,7 +34,7 @@ TUWF::get qr{/r}, sub { my $opt = tuwf->validate(get => q => { onerror => undef }, p => { upage => 1 }, - f => { advsearch => 'r' }, + f => { advsearch_err => 'r' }, s => { onerror => 'title', enum => [qw/released minage title/] }, o => { onerror => 'a', enum => ['a','d'] }, fil => { required => 0 }, diff --git a/lib/VNWeb/TT/TagPage.pm b/lib/VNWeb/TT/TagPage.pm index 8431419e..8242e05a 100644 --- a/lib/VNWeb/TT/TagPage.pm +++ b/lib/VNWeb/TT/TagPage.pm @@ -97,7 +97,7 @@ sub vns_ { my $opt = tuwf->validate(get => p => { upage => 1 }, - f => { advsearch => 'v' }, + f => { advsearch_err => 'v' }, s => { onerror => 'tagscore', enum => [qw/tagscore title rel pop rating/] }, o => { onerror => 'd', enum => ['a','d'] }, m => { onerror => [auth->pref('spoilers')||0], type => 'array', scalar => 1, minlength => 1, values => { enum => [0..2] } }, diff --git a/lib/VNWeb/VN/List.pm b/lib/VNWeb/VN/List.pm index ce780cef..7e19f2de 100644 --- a/lib/VNWeb/VN/List.pm +++ b/lib/VNWeb/VN/List.pm @@ -78,7 +78,7 @@ TUWF::get qr{/v(?:/(?<char>all|[a-z0]))?}, sub { q => { onerror => undef }, sq=> { onerror => undef }, p => { upage => 1 }, - f => { advsearch => 'v' }, + f => { advsearch_err => 'v' }, s => { onerror => 'title', enum => [qw/title rel pop rating/] }, o => { onerror => 'a', enum => ['a','d'] }, ch=> { onerror => [], type => 'array', scalar => 1, values => { onerror => undef, enum => ['0', 'a'..'z'] } }, |