From 5184b0f41aabb79a47e8d3b8c76b88ca04a53b24 Mon Sep 17 00:00:00 2001
From: Eugenij <eugenijm@protonmail.com>
Date: Wed, 3 Jul 2019 10:19:51 +0000
Subject: [PATCH] Use fallback values for search queries

This is to make sure the entire request doesn't return a 500 error if
user or status search times out.
---
 CHANGELOG.md                                   |  1 +
 .../web/mastodon_api/search_controller.ex      | 18 ++++++++++++++----
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8a0dad453..aefc09177 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
 ### Fixed
 - Not being able to pin unlisted posts
+- Mastodon API: Handling of search timeouts (`/api/v1/search` and `/api/v2/search`)
 
 ### Changed
 - Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text
diff --git a/lib/pleroma/web/mastodon_api/search_controller.ex b/lib/pleroma/web/mastodon_api/search_controller.ex
index 0d1e2355d..efa9cc788 100644
--- a/lib/pleroma/web/mastodon_api/search_controller.ex
+++ b/lib/pleroma/web/mastodon_api/search_controller.ex
@@ -17,8 +17,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
   plug(Pleroma.Plugs.RateLimiter, :search when action in [:search, :search2, :account_search])
 
   def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
-    accounts = User.search(query, search_options(params, user))
-    statuses = Activity.search(user, query)
+    accounts = with_fallback(fn -> User.search(query, search_options(params, user)) end, [])
+    statuses = with_fallback(fn -> Activity.search(user, query) end, [])
     tags_path = Web.base_url() <> "/tag/"
 
     tags =
@@ -40,8 +40,8 @@ def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
   end
 
   def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
-    accounts = User.search(query, search_options(params, user))
-    statuses = Activity.search(user, query)
+    accounts = with_fallback(fn -> User.search(query, search_options(params, user)) end, [])
+    statuses = with_fallback(fn -> Activity.search(user, query) end, [])
 
     tags =
       query
@@ -76,4 +76,14 @@ defp search_options(params, user) do
       for_user: user
     ]
   end
+
+  defp with_fallback(f, fallback) do
+    try do
+      f.()
+    rescue
+      error ->
+        Logger.error("#{__MODULE__} search error: #{inspect(error)}")
+        fallback
+    end
+  end
 end