# Buggy code
def search(self, search_params, age=0, ep_obj=None):  # pylint: disable=too-many-locals
    results = []
    if not self.login():
        return results

    for mode in search_params:
        items = []
        logger.log("Search Mode: {}".format(mode), logger.DEBUG)
        for search_string in search_params[mode]:
            if mode != "RSS":
                logger.log(
                    "Search string: {}".format(search_string.decode("utf-8")),
                    logger.DEBUG,
                )

            search_string = "+".join(search_string.split())

            post_data = dict(
                {
                    "/browse.php?": None,
                    "cata": "yes",
                    "jxt": 8,
                    "jxw": "b",
                    "search": search_string,
                },
                **self.categories[mode],
            )

            if self.freeleech:
                post_data.update({"free": "on"})

            parsedJSON = self.get_url(
                self.urls["search"], post_data=post_data, returns="json"
            )
            if not parsedJSON:
                logger.log("No data returned from provider", logger.DEBUG)
                continue

            try:
                torrents = parsedJSON.get("Fs", [])[0].get("Cn", {}).get("torrents", [])
            except Exception:
                logger.log(
                    "Data returned from provider does not contain any torrents",
                    logger.DEBUG,
                )
                continue

            for torrent in torrents:
                title = (
                    re.sub(r"\[.*\=.*\].*\[/.*\]", "", torrent["name"])
                    if torrent["name"]
                    else None
                )
                download_url = (
                    urljoin(
                        self.urls["download"],
                        "{}/{}".format(torrent["id"], torrent["fname"]),
                    )
                    if torrent["id"] and torrent["fname"]
                    else None
                )

                if not all([title, download_url]):
                    continue

                seeders = int(torrent["seed"]) if torrent["seed"] else 1
                leechers = int(torrent["leech"]) if torrent["leech"] else 0

                # Filter unseeded torrent
                if seeders < min(self.minseed, 1):
                    if mode != "RSS":
                        logger.log(
                            "Discarding torrent because it doesn't meet the minimum seeders: {0}. Seeders: {1})".format(
                                title, seeders
                            ),
                            logger.DEBUG,
                        )
                    continue

                torrent_size = torrent["size"]
                size = convert_size(torrent_size) or -1

                item = {
                    "title": title,
                    "link": download_url,
                    "size": size,
                    "seeders": seeders,
                    "leechers": leechers,
                    "pubdate": None,
                    "hash": None,
                }

                if mode != "RSS":
                    logger.log(
                        "Found result: {0} with {1} seeders and {2} leechers".format(
                            title, seeders, leechers
                        ),
                        logger.DEBUG,
                    )

                items.append(item)

        # For each search mode sort all the items by seeders if available
        items.sort(key=lambda d: try_int(d.get("seeders", 0)), reverse=True)
        results += items

    return results


# Traceback (ValueError)
SEARCHQUEUE-MANUAL-311937 :: [TorrentDay] :: [3351698] Unknown exception while searching TorrentDay. Error: 'No JSON object could be decoded'
Traceback (most recent call last):
File "/home/home/SickRage/sickbeard/search.py", line 547, in searchProviders
forced_search, downCurQuality, manual_search, manual_search_type)
File "/home/home/SickRage/sickrage/providers/GenericProvider.py", line 149, in find_search_results
items_list += self.search(search_string, ep_obj=episode)
File "/home/home/SickRage/sickbeard/providers/torrentday.py", line 123, in search
parsedJSON = self.get_url(self.urls['search'], post_data=post_data, returns='json')
File "/home/home/SickRage/sickrage/providers/GenericProvider.py", line 356, in get_url
return getURL(url, post_data, params, self.headers, timeout, self.session, **kwargs)
File "/home/home/SickRage/sickbeard/helpers.py", line 1472, in getURL
return resp if response_type == u'response' or response_type is None else resp.json() if response_type == u'json' else getattr(resp, response_type, resp)
File "/home/home/SickRage/lib/requests/models.py", line 808, in json
return complexjson.loads(self.text, **kwargs)
File "/home/home/SickRage/lib/simplejson/__init__.py", line 307, in loads
return _default_decoder.decode(s)
File "/home/home/SickRage/lib/simplejson/decoder.py", line 335, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/home/home/SickRage/lib/simplejson/decoder.py", line 353, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

# Fixed code
def search(self, search_params, age=0, ep_obj=None):  # pylint: disable=too-many-locals
    results = []
    if not self.login():
        return results

    for mode in search_params:
        items = []
        logger.log("Search Mode: {}".format(mode), logger.DEBUG)
        for search_string in search_params[mode]:
            if mode != "RSS":
                logger.log(
                    "Search string: {}".format(search_string.decode("utf-8")),
                    logger.DEBUG,
                )

            search_string = "+".join(search_string.split())

            post_data = dict(
                {
                    "/browse.php?": None,
                    "cata": "yes",
                    "jxt": 8,
                    "jxw": "b",
                    "search": search_string,
                },
                **self.categories[mode],
            )

            if self.freeleech:
                post_data.update({"free": "on"})

            try:
                response = self.get_url(self.urls["search"], post_data=post_data)
                response.raise_for_status()
            except RequestException as msg:
                logger.log(
                    "Error while connecting to provider: {error}".format(error=msg),
                    logger.ERROR,
                )
                continue

            try:
                jdata = response.json()
            except (
                ValueError
            ):  # also catches JSONDecodeError if simplejson is installed
                logger.log("Data returned from provider is not json", logger.ERROR)
                continue

            torrents = jdata.get("Fs", [dict()])[0].get("Cn", {}).get("torrents", [])
            if not torrents:
                logger.log(
                    "Data returned from provider does not contain any torrents",
                    logger.DEBUG,
                )
                continue

            for torrent in torrents:
                title = (
                    re.sub(r"\[.*\=.*\].*\[/.*\]", "", torrent["name"])
                    if torrent["name"]
                    else None
                )
                download_url = (
                    urljoin(
                        self.urls["download"],
                        "{}/{}".format(torrent["id"], torrent["fname"]),
                    )
                    if torrent["id"] and torrent["fname"]
                    else None
                )

                if not all([title, download_url]):
                    continue

                seeders = int(torrent["seed"]) if torrent["seed"] else 1
                leechers = int(torrent["leech"]) if torrent["leech"] else 0

                # Filter unseeded torrent
                if seeders < min(self.minseed, 1):
                    if mode != "RSS":
                        logger.log(
                            "Discarding torrent because it doesn't meet the minimum seeders: {0}. Seeders: {1})".format(
                                title, seeders
                            ),
                            logger.DEBUG,
                        )
                    continue

                torrent_size = torrent["size"]
                size = convert_size(torrent_size) or -1

                item = {
                    "title": title,
                    "link": download_url,
                    "size": size,
                    "seeders": seeders,
                    "leechers": leechers,
                    "pubdate": None,
                    "hash": None,
                }

                if mode != "RSS":
                    logger.log(
                        "Found result: {0} with {1} seeders and {2} leechers".format(
                            title, seeders, leechers
                        ),
                        logger.DEBUG,
                    )

                items.append(item)

        # For each search mode sort all the items by seeders if available
        items.sort(key=lambda d: try_int(d.get("seeders", 0)), reverse=True)
        results += items

    return results