mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-10 23:25:31 +08:00
Add FailureNotifiableJob jobs concerns for creating failure notifications for users [SCI-9119] (#6147)
This commit is contained in:
parent
d671471b44
commit
eea24a69e9
9 changed files with 146 additions and 76 deletions
|
@ -835,7 +835,7 @@ class ProtocolsController < ApplicationController
|
|||
temp_files_ids << temp_file.id
|
||||
end
|
||||
end
|
||||
@job = Protocols::DocxImportJob.perform_later(temp_files_ids, current_user.id, current_team.id)
|
||||
@job = Protocols::DocxImportJob.perform_later(temp_files_ids, user_id: current_user.id, team_id: current_team.id)
|
||||
render json: { job_id: @job.job_id }
|
||||
end
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ class ReportsController < ApplicationController
|
|||
log_activity(:generate_docx_report)
|
||||
|
||||
ensure_report_template!
|
||||
Reports::DocxJob.perform_later(@report.id, current_user.id, root_url)
|
||||
Reports::DocxJob.perform_later(@report.id, user_id: current_user.id, root_url: root_url)
|
||||
render json: {
|
||||
message: I18n.t('projects.reports.index.generation.accepted_message')
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ class ReportsController < ApplicationController
|
|||
log_activity(:generate_pdf_report)
|
||||
|
||||
ensure_report_template!
|
||||
Reports::PdfJob.perform_later(@report.id, current_user.id)
|
||||
Reports::PdfJob.perform_later(@report.id, user_id: current_user.id)
|
||||
end
|
||||
|
||||
def ensure_report_template!
|
||||
|
|
|
@ -349,7 +349,7 @@ class RepositoriesController < ApplicationController
|
|||
repositories = Repository.viewable_by_user(current_user, current_team).where(id: params[:repository_ids])
|
||||
if repositories.present? && current_user.has_available_exports?
|
||||
current_user.increase_daily_exports_counter!
|
||||
RepositoriesExportJob.perform_later(repositories.pluck(:id), current_user.id, current_team)
|
||||
RepositoriesExportJob.perform_later(repositories.pluck(:id), user_id: current_user.id, team_id: current_team.id)
|
||||
render json: { message: t('zip_export.export_request_success') }
|
||||
else
|
||||
render json: { message: t('zip_export.export_error') }, status: :unprocessable_entity
|
||||
|
|
45
app/jobs/concerns/failed_deivery_notifiable_job.rb
Normal file
45
app/jobs/concerns/failed_deivery_notifiable_job.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module FailedDeliveryNotifiableJobJob
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
before_enqueue do |job|
|
||||
unless job.arguments.last.is_a?(Hash) && job.arguments.last[:user_id].present?
|
||||
raise ArgumentError, 'required :user_id argument is missing! Needed for user notification in case of failure.'
|
||||
end
|
||||
end
|
||||
|
||||
rescue_from StandardError do |e|
|
||||
logger.error e.message
|
||||
logger.error e.backtrace.join("\n")
|
||||
create_failed_notification!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_failed_notification!
|
||||
@user = User.find_by(id: arguments.last[:user_id])
|
||||
return if @user.blank?
|
||||
|
||||
notification = Notification.create!(
|
||||
type_of: :deliver_error,
|
||||
title: failed_notification_title,
|
||||
message: failed_notification_message
|
||||
)
|
||||
notification.create_user_notification(@user)
|
||||
end
|
||||
|
||||
def failed_notification_title
|
||||
I18n.t('activejob.failure_notifiable_job.general_notification_title')
|
||||
end
|
||||
|
||||
def failed_notification_message
|
||||
I18n.backend.date_format = @user.settings[:date_format]
|
||||
timestamp = I18n.l(enqueued_at.in_time_zone(@user.time_zone), format: :full)
|
||||
I18n.t('activejob.failure_notifiable_job.general_notification_message', request_timestamp: timestamp)
|
||||
ensure
|
||||
I18n.backend.date_format = nil
|
||||
end
|
||||
end
|
|
@ -3,10 +3,11 @@
|
|||
module Protocols
|
||||
class DocxImportJob < ApplicationJob
|
||||
include RenamingUtil
|
||||
include FailedDeliveryNotifiableJob
|
||||
|
||||
class RequestFailureException < StandardError; end
|
||||
|
||||
def perform(temp_files_ids, user_id, team_id)
|
||||
def perform(temp_files_ids, user_id:, team_id:)
|
||||
@user = User.find(user_id)
|
||||
@team = @user.teams.find(team_id)
|
||||
@tmp_files = TempFile.where(id: temp_files_ids)
|
||||
|
@ -30,10 +31,7 @@ module Protocols
|
|||
}
|
||||
)
|
||||
|
||||
unless response.success?
|
||||
create_failed_notification!
|
||||
raise RequestFailureException, "#{response.code}: #{response.message}"
|
||||
end
|
||||
raise RequestFailureException, "#{response.code}: #{response.message}" unless response.success?
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@protocol = @team.protocols.new(
|
||||
|
@ -50,9 +48,6 @@ module Protocols
|
|||
@protocol.save!
|
||||
create_steps!(response['steps']) if response['steps'].present?
|
||||
create_notification!
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
create_failed_notification!
|
||||
Rails.logger.error(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -153,13 +148,14 @@ module Protocols
|
|||
UserNotification.create!(notification: notification, user: @user)
|
||||
end
|
||||
|
||||
def create_failed_notification!
|
||||
notification = Notification.create!(
|
||||
type_of: :deliver_error,
|
||||
title: I18n.t('protocols.import_export.import_protocol_notification_error.title')
|
||||
)
|
||||
# Overrides method from FailedDeliveryNotifiableJob concern
|
||||
def failed_notification_title
|
||||
I18n.t('protocols.import_export.import_protocol_notification_error.title')
|
||||
end
|
||||
|
||||
UserNotification.create!(notification: notification, user: @user)
|
||||
# Overrides method from FailedDeliveryNotifiableJob concern
|
||||
def failed_notification_message
|
||||
I18n.t('protocols.import_export.import_protocol_notification_error.message')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,36 +4,11 @@ module Reports
|
|||
class DocxJob < ApplicationJob
|
||||
extend InputSanitizeHelper
|
||||
include InputSanitizeHelper
|
||||
include FailedDeliveryNotifiableJob
|
||||
|
||||
queue_as :reports
|
||||
|
||||
discard_on StandardError do |job, error|
|
||||
report = Report.find_by(id: job.arguments.first)
|
||||
next unless report
|
||||
|
||||
ActiveRecord::Base.no_touching do
|
||||
report.docx_error!
|
||||
end
|
||||
report_path =
|
||||
if report.docx_file.attached?
|
||||
Rails.application.routes.url_helpers
|
||||
.reports_path(team: report.team.id, preview_report_id: report.id, preview_type: :docx)
|
||||
else
|
||||
Rails.application.routes.url_helpers.reports_path(team: report.team.id)
|
||||
end
|
||||
user = User.find(job.arguments.second)
|
||||
notification = Notification.create(
|
||||
type_of: :deliver_error,
|
||||
title: I18n.t('projects.reports.index.generation.error_docx_notification_title'),
|
||||
message: I18n.t('projects.reports.index.generation.error_notification_message',
|
||||
report_link: "<a href='#{report_path}'>#{escape_input(report.name)}</a>",
|
||||
team_name: escape_input(report.team.name))
|
||||
)
|
||||
notification.create_user_notification(user)
|
||||
Rails.logger.error("Couldn't generate DOCX for Report with id: #{report.id}. Error:\n #{error}")
|
||||
end
|
||||
|
||||
def perform(report_id, user_id, root_url)
|
||||
def perform(report_id, user_id:, root_url:)
|
||||
report = Report.find(report_id)
|
||||
user = User.find(user_id)
|
||||
file = Tempfile.new(['report', '.docx'])
|
||||
|
@ -61,6 +36,39 @@ module Reports
|
|||
file.close
|
||||
file.unlink
|
||||
end
|
||||
rescue StandardError => e
|
||||
raise e if report.blank?
|
||||
|
||||
ActiveRecord::Base.no_touching do
|
||||
report.docx_error!
|
||||
end
|
||||
Rails.logger.error("Couldn't generate DOCX for Report with id: #{report.id}. Error:\n #{e.message}")
|
||||
raise e
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Overrides method from FailedDeliveryNotifiableJob concern
|
||||
def failed_notification_title
|
||||
I18n.t('projects.reports.index.generation.error_docx_notification_title')
|
||||
end
|
||||
|
||||
# Overrides method from FailedDeliveryNotifiableJob concern
|
||||
def failed_notification_message
|
||||
report = Report.find_by(id: arguments.first)
|
||||
return '' if report.blank?
|
||||
|
||||
report_path =
|
||||
if report.docx_file.attached?
|
||||
Rails.application.routes.url_helpers
|
||||
.reports_path(team: report.team.id, preview_report_id: report.id, preview_type: :docx)
|
||||
else
|
||||
Rails.application.routes.url_helpers.reports_path(team: report.team.id)
|
||||
end
|
||||
|
||||
I18n.t('projects.reports.index.generation.error_notification_message',
|
||||
report_link: "<a href='#{report_path}'>#{escape_input(report.name)}</a>",
|
||||
team_name: escape_input(report.team.name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,40 +6,15 @@ module Reports
|
|||
include InputSanitizeHelper
|
||||
include ReportsHelper
|
||||
include Canaid::Helpers::PermissionsHelper
|
||||
include FailedDeliveryNotifiableJob
|
||||
|
||||
PDFUNITE_ENCRYPTED_PDF_ERROR_STRING = 'Unimplemented Feature: Could not merge encrypted files'
|
||||
|
||||
queue_as :reports
|
||||
|
||||
discard_on StandardError do |job, error|
|
||||
report = Report.find_by(id: job.arguments.first)
|
||||
next unless report
|
||||
|
||||
ActiveRecord::Base.no_touching do
|
||||
report.pdf_error!
|
||||
end
|
||||
report_path =
|
||||
if report.pdf_file.attached?
|
||||
Rails.application.routes.url_helpers
|
||||
.reports_path(team: report.team.id, preview_report_id: report.id, preview_type: :pdf)
|
||||
else
|
||||
Rails.application.routes.url_helpers.reports_path(team: report.team.id)
|
||||
end
|
||||
user = User.find(job.arguments.second)
|
||||
notification = Notification.create(
|
||||
type_of: :deliver_error,
|
||||
title: I18n.t('projects.reports.index.generation.error_pdf_notification_title'),
|
||||
message: I18n.t('projects.reports.index.generation.error_notification_message',
|
||||
report_link: "<a href='#{report_path}'>#{escape_input(report.name)}</a>",
|
||||
team_name: escape_input(report.team.name))
|
||||
)
|
||||
notification.create_user_notification(user)
|
||||
Rails.logger.error("Couldn't generate PDF for Report with id: #{report.id}. Error:\n #{error}")
|
||||
end
|
||||
|
||||
PREVIEW_EXTENSIONS = %w(docx pdf).freeze
|
||||
|
||||
def perform(report_id, user_id)
|
||||
def perform(report_id, user_id:)
|
||||
report = Report.find(report_id)
|
||||
user = User.find(user_id)
|
||||
file = Tempfile.new(['report', '.pdf'], binmode: true)
|
||||
|
@ -97,6 +72,14 @@ module Reports
|
|||
I18n.backend.date_format = nil
|
||||
file.close(true)
|
||||
end
|
||||
rescue StandardError => e
|
||||
raise e if report.blank?
|
||||
|
||||
ActiveRecord::Base.no_touching do
|
||||
report.pdf_error!
|
||||
end
|
||||
Rails.logger.error("Couldn't generate PDF for Report with id: #{report.id}. Error:\n #{e.message}")
|
||||
raise e
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -195,5 +178,27 @@ module Reports
|
|||
'scinote_logo.svg'
|
||||
end
|
||||
|
||||
# Overrides method from FailedDeliveryNotifiableJob concern
|
||||
def failed_notification_title
|
||||
I18n.t('projects.reports.index.generation.error_pdf_notification_title')
|
||||
end
|
||||
|
||||
# Overrides method from FailedDeliveryNotifiableJob concern
|
||||
def failed_notification_message
|
||||
report = Report.find_by(id: arguments.first)
|
||||
return '' if report.blank?
|
||||
|
||||
report_path =
|
||||
if report.pdf_file.attached?
|
||||
Rails.application.routes.url_helpers
|
||||
.reports_path(team: report.team.id, preview_report_id: report.id, preview_type: :pdf)
|
||||
else
|
||||
Rails.application.routes.url_helpers.reports_path(team: report.team.id)
|
||||
end
|
||||
|
||||
I18n.t('projects.reports.index.generation.error_notification_message',
|
||||
report_link: "<a href='#{report_path}'>#{escape_input(report.name)}</a>",
|
||||
team_name: escape_input(report.team.name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
class RepositoriesExportJob < ApplicationJob
|
||||
include StringUtility
|
||||
include FailedDeliveryNotifiableJob
|
||||
|
||||
def perform(repository_ids, user_id, team)
|
||||
def perform(repository_ids, user_id:, team_id:)
|
||||
@user = User.find(user_id)
|
||||
@team = team
|
||||
@team = Team.find(team_id)
|
||||
@repositories = Repository.viewable_by_user(@user, @team).where(id: repository_ids).order(:id)
|
||||
zip_input_dir = FileUtils.mkdir_p(Rails.root.join("tmp/temp_zip_#{Time.now.to_i}")).first
|
||||
zip_dir = FileUtils.mkdir_p(Rails.root.join('tmp/zip-ready')).first
|
||||
|
@ -95,4 +96,9 @@ class RepositoriesExportJob < ApplicationJob
|
|||
)
|
||||
UserNotification.create!(notification: notification, user: @user)
|
||||
end
|
||||
|
||||
# Overrides method from FailedDeliveryNotifiableJob concern
|
||||
def failed_notification_title
|
||||
I18n.t('repositories.index.export.notification.error.title')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -253,6 +253,11 @@ en:
|
|||
full_name: "Full name"
|
||||
initials: "Initials"
|
||||
avatar: "Avatar"
|
||||
|
||||
activejob:
|
||||
failure_notifiable_job:
|
||||
general_notification_title: "Your export failed. Please contact support."
|
||||
general_notification_message: "Request timestamp: %{request_timestamp}"
|
||||
|
||||
head:
|
||||
title: "SciNote | %{title}"
|
||||
|
@ -1892,6 +1897,10 @@ en:
|
|||
all_teams: "All teams (current & new)"
|
||||
all_teams_tooltip: "This will disable individual team settings"
|
||||
success_message: "Selected sharing options for the Inventory %{inventory_name} have been saved."
|
||||
export:
|
||||
notification:
|
||||
error:
|
||||
title: "Your Inventories export failed. Please contact support."
|
||||
show:
|
||||
name: "Name"
|
||||
archived_inventory_items: "%{repository_name} archived items"
|
||||
|
@ -2773,7 +2782,7 @@ en:
|
|||
body_html: 'The protocol has been successfully imported. You can access the draft of protocol template <a href="%{url}">here.</a>'
|
||||
failed:
|
||||
title: "Import failed"
|
||||
body_html: "We're sorry, but the file import has failed. Please ensure you have a stable internet connection and try again. If the problem persists, please contact support for further assistance."
|
||||
body_html: "We're sorry but the file import process has encountered an error. Please make another attempt, and if the issue persists, please contact support for further assistance."
|
||||
import: "Import"
|
||||
cancel: "Cancel"
|
||||
close: "Close"
|
||||
|
@ -2872,7 +2881,8 @@ en:
|
|||
title: "The import process has been successfully completed. You can download original file here: %{link}"
|
||||
message: "Protocol template:"
|
||||
import_protocol_notification_error:
|
||||
title: "We're sorry, but the file import has failed. Please ensure you have a stable internet connection and try again. If the problem persists, please contact support for further assistance."
|
||||
title: "Import failed"
|
||||
message: "We're sorry but the file import process has encountered an error. Please make another attempt, and if the issue persists, please contact support for further assistance."
|
||||
export:
|
||||
export_results:
|
||||
title: "Export results"
|
||||
|
|
Loading…
Add table
Reference in a new issue