diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index 8bf9da2cfd..bf7deac5cf 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -8,6 +8,7 @@ class Api::BaseController < ApplicationController
include Api::AccessTokenTrackingConcern
include Api::CachingConcern
include Api::ContentSecurityPolicy
+ include Api::ErrorHandling
skip_before_action :require_functional!, unless: :limited_federation_mode?
@@ -18,51 +19,6 @@ class Api::BaseController < ApplicationController
protect_from_forgery with: :null_session
- rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
- render json: { error: e.to_s }, status: 422
- end
-
- rescue_from ActiveRecord::RecordNotUnique do
- render json: { error: 'Duplicate record' }, status: 422
- end
-
- rescue_from Date::Error do
- render json: { error: 'Invalid date supplied' }, status: 422
- end
-
- rescue_from ActiveRecord::RecordNotFound do
- render json: { error: 'Record not found' }, status: 404
- end
-
- rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do
- render json: { error: 'Remote data could not be fetched' }, status: 503
- end
-
- rescue_from OpenSSL::SSL::SSLError do
- render json: { error: 'Remote SSL certificate could not be verified' }, status: 503
- end
-
- rescue_from Mastodon::NotPermittedError do
- render json: { error: 'This action is not allowed' }, status: 403
- end
-
- rescue_from Seahorse::Client::NetworkingError do |e|
- Rails.logger.warn "Storage server error: #{e}"
- render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
- end
-
- rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight do
- render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
- end
-
- rescue_from Mastodon::RateLimitExceededError do
- render json: { error: I18n.t('errors.429') }, status: 429
- end
-
- rescue_from ActionController::ParameterMissing, Mastodon::InvalidParameterError do |e|
- render json: { error: e.to_s }, status: 400
- end
-
def doorkeeper_unauthorized_render_options(error: nil)
{ json: { error: error.try(:description) || 'Not authorized' } }
end
diff --git a/app/controllers/concerns/api/error_handling.rb b/app/controllers/concerns/api/error_handling.rb
new file mode 100644
index 0000000000..ad559fe2d7
--- /dev/null
+++ b/app/controllers/concerns/api/error_handling.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Api::ErrorHandling
+ extend ActiveSupport::Concern
+
+ included do
+ rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
+ render json: { error: e.to_s }, status: 422
+ end
+
+ rescue_from ActiveRecord::RecordNotUnique do
+ render json: { error: 'Duplicate record' }, status: 422
+ end
+
+ rescue_from Date::Error do
+ render json: { error: 'Invalid date supplied' }, status: 422
+ end
+
+ rescue_from ActiveRecord::RecordNotFound do
+ render json: { error: 'Record not found' }, status: 404
+ end
+
+ rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do
+ render json: { error: 'Remote data could not be fetched' }, status: 503
+ end
+
+ rescue_from OpenSSL::SSL::SSLError do
+ render json: { error: 'Remote SSL certificate could not be verified' }, status: 503
+ end
+
+ rescue_from Mastodon::NotPermittedError do
+ render json: { error: 'This action is not allowed' }, status: 403
+ end
+
+ rescue_from Seahorse::Client::NetworkingError do |e|
+ Rails.logger.warn "Storage server error: #{e}"
+ render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
+ end
+
+ rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight do
+ render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
+ end
+
+ rescue_from Mastodon::RateLimitExceededError do
+ render json: { error: I18n.t('errors.429') }, status: 429
+ end
+
+ rescue_from ActionController::ParameterMissing, Mastodon::InvalidParameterError do |e|
+ render json: { error: e.to_s }, status: 400
+ end
+ end
+end
diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js
index 30b7601d5d..b54cbe27b9 100644
--- a/app/javascript/mastodon/actions/notifications.js
+++ b/app/javascript/mastodon/actions/notifications.js
@@ -552,7 +552,10 @@ export const fetchNotificationsForRequest = accountId => (dispatch, getState) =>
api(getState).get('/api/v1/notifications', { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data.map(item => item.account)));
dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
+ dispatch(importFetchedAccounts(response.data.filter(item => item.report).map(item => item.report.target_account)));
+
dispatch(fetchNotificationsForRequestSuccess(response.data, next?.uri));
}).catch(err => {
dispatch(fetchNotificationsForRequestFail(err));
@@ -585,7 +588,10 @@ export const expandNotificationsForRequest = () => (dispatch, getState) => {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data.map(item => item.account)));
dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
+ dispatch(importFetchedAccounts(response.data.filter(item => item.report).map(item => item.report.target_account)));
+
dispatch(expandNotificationsForRequestSuccess(response.data, next?.uri));
}).catch(err => {
dispatch(expandNotificationsForRequestFail(err));
diff --git a/app/javascript/mastodon/components/column_header.jsx b/app/javascript/mastodon/components/column_header.jsx
index 8b7dcebc67..7fd646690d 100644
--- a/app/javascript/mastodon/components/column_header.jsx
+++ b/app/javascript/mastodon/components/column_header.jsx
@@ -199,7 +199,7 @@ class ColumnHeader extends PureComponent {
{hasTitle && (
<>
- {backButton}
+ {showBackButton && backButton}