shlinkio / shlink

The definitive self-hosted URL shortener
https://shlink.io
MIT License
3.13k stars 253 forks source link

500 Internal Server Error when filtering by tags with tagsMode=all and searchTerm at the same time #1458

Closed lukaslabryszewski closed 2 years ago

lukaslabryszewski commented 2 years ago

How Shlink is set-up

Summary

A 500 Internal Server Error occurs while filtering by tags with tagsMode=all and searchTerm at the same time.

Current behavior

It's throwing the following Doctrine ORM QueryException in logs:

Shlink.ERROR - Doctrine\ORM\Query\QueryException: SELECT DISTINCT s FROM Shlinkio\Shlink\Core\Entity\ShortUrl s LEFT JOIN s.domain d INNER JOIN s.tags t_0 WITH t_0.name = :tag0 INNER JOIN s.tags t_1 WITH t_1.name = :tag1 INNER JOIN s.tags t_2 WITH t_2.name = :tag2 INNER JOIN s.tags t_3 WITH t_3.name = :tag3 WHERE 1=1 AND s.dateCreated >= :startDate AND s.dateCreated <= :endDate AND (s.longUrl LIKE :searchPattern OR s.shortCode LIKE :searchPattern OR s.title LIKE :searchPattern OR t.name LIKE :searchPattern OR d.authority LIKE :searchPattern) ORDER BY s.dateCreated DESC in /var/www/gsl.cards/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:21

Full Stack Trace: shlink-tags-error-053122.txt

Expected behavior

It should return properly filtered results.

How to reproduce

Example Request:

$ curl -X 'GET' \
  'https://shlink.local/rest/v2/short-urls?searchTerm=test&tags%5B%5D=tag1&tagsMode=all' \
  -H 'accept: application/json' \
  -H 'X-Api-Key: API_KEY'

Response:

{"title":"Internal Server Error","type":"INTERNAL_SERVER_ERROR","status":500,"detail":"An unknown error occurred."}
acelaya commented 2 years ago

Thanks!

acelaya commented 2 years ago

So, the issue is a bit tricky to solve.

Shlink has always taken into consideration tag names for the filtering when providing a search term (it basically tries to match in the long URL, short code, title, domain and tags fields, including the result if any of them matches).

However, in order to allow searching by a full list of tags, I had to change how the tags and short URLs tables are joined, by making short URLs table join with the tags table for every provided tag, and match every join by tag name.

This basically makes it impossible to search by tag name on the search term, when you are also filtering by "ALL" tags, unless the search term is also one of those tags, which is useless.

Because of that, I'm going to exlcude the tag name from the search term filtering when the tags mode is ALL, as it adds very little value and it seems to not be possible to achive anyway.

When the tags mode is ANY or no tags are provided, the search term will continue applying to the tags name.

acelaya commented 2 years ago

I have just published v3.1.2, which includes a fix for this.

The docker image will be available once this build finishes https://github.com/shlinkio/shlink/runs/6737418378?check_suite_focus=true (around 1.5h)

lukaslabryszewski commented 2 years ago

Thank you very much @acelaya . Much appreciated.

We will update and test it out.

And thank you for explaining. I wasn't aware that searchTerm also searches tags. Is this for backwards compatibility?