FEATURE: Improve channel error visibility in the admin panel, stop adding chat integration errors to logs

This commit is contained in:
David Taylor 2018-08-20 12:05:59 +01:00
parent c44ac56d32
commit fc721a1768
12 changed files with 119 additions and 68 deletions

View File

@ -1,6 +1,6 @@
class DiscourseChat::Channel < DiscourseChat::PluginModel
# Setup ActiveRecord::Store to use the JSON field to read/write these values
store :value, accessors: [ :provider, :error_key, :data ], coder: JSON
store :value, accessors: [ :provider, :error_key, :error_info, :data ], coder: JSON
scope :with_provider, ->(provider) { where("value::json->>'provider'=?", provider) }
scope :with_data_value, ->(key, value) { where("(value::json->>'data')::json->>?=?", key.to_s, value.to_s) }

View File

@ -1,7 +1,7 @@
require_relative './rule_serializer'
class DiscourseChat::ChannelSerializer < ApplicationSerializer
attributes :id, :provider, :error_key, :data, :rules
attributes :id, :provider, :error_key, :error_info, :data, :rules
def rules
object.rules.order_by_precedence.map do |rule|

View File

@ -86,15 +86,16 @@ module DiscourseChat
else
channel.update_attribute('error_key', 'chat_integration.channel_exception')
end
channel.update_attribute('error_info', JSON.pretty_generate(e.try(:info)))
# Log the error
Discourse.handle_job_exception(e,
message: "Triggering notifications failed",
extra: { provider_name: provider::PROVIDER_NAME,
channel: rule.channel,
post_id: post.id,
error_info: e.class == DiscourseChat::ProviderError ? e.info : nil }
)
# Discourse.handle_job_exception(e,
# message: "Triggering notifications failed",
# extra: { provider_name: provider::PROVIDER_NAME,
# channel: rule.channel,
# post_id: post.id,
# error_info: e.class == DiscourseChat::ProviderError ? e.info : nil }
# )
end
end

View File

@ -1,41 +1,48 @@
import { popupAjaxError } from 'discourse/lib/ajax-error';
import { popupAjaxError } from "discourse/lib/ajax-error";
export default Ember.Component.extend({
classNames: ['channel-details'],
classNames: ["channel-details"],
actions: {
refresh: function(){
this.sendAction('refresh');
refresh: function() {
this.sendAction("refresh");
},
delete(channel){
bootbox.confirm(I18n.t("chat_integration.channel_delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => {
if (result) {
channel.destroyRecord().then(() => {
this.send('refresh');
}).catch(popupAjaxError);
delete(channel) {
bootbox.confirm(
I18n.t("chat_integration.channel_delete_confirm"),
I18n.t("no_value"),
I18n.t("yes_value"),
result => {
if (result) {
channel
.destroyRecord()
.then(() => {
this.send("refresh");
})
.catch(popupAjaxError);
}
}
});
);
},
edit(channel){
this.sendAction('edit', channel);
edit(channel) {
this.sendAction("edit", channel);
},
test(channel){
this.sendAction('test', channel);
test(channel) {
this.sendAction("test", channel);
},
createRule(channel){
this.sendAction('createRule', channel);
createRule(channel) {
this.sendAction("createRule", channel);
},
editRule(rule){
this.sendAction('editRule', rule, this.get('channel'));
},
showError(errorKey){
bootbox.alert(I18n.t(errorKey));
editRule(rule) {
this.sendAction("editRule", rule, this.get("channel"));
},
showError(channel) {
this.sendAction("showError", channel);
}
}
});

View File

@ -1,14 +1,14 @@
import showModal from 'discourse/lib/show-modal';
import showModal from "discourse/lib/show-modal";
import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend({
modalShowing: false,
@computed('model.channels')
@computed("model.channels")
anyErrors(channels) {
let anyErrors = false;
channels.forEach((channel) => {
channels.forEach(channel => {
if (channel.error_key) {
anyErrors = true;
}
@ -17,57 +17,78 @@ export default Ember.Controller.extend({
return anyErrors;
},
actions:{
actions: {
createChannel() {
this.set('modalShowing', true);
this.set("modalShowing", true);
const model = {
channel: this.store.createRecord('channel', { provider: this.get('model.provider.id'), data:{} }),
provider: this.get('model.provider')
channel: this.store.createRecord("channel", {
provider: this.get("model.provider.id"),
data: {}
}),
provider: this.get("model.provider")
};
showModal('admin-plugins-chat-edit-channel', { model: model, admin: true });
showModal("admin-plugins-chat-edit-channel", {
model: model,
admin: true
});
},
editChannel(channel) {
this.set('modalShowing', true);
this.set("modalShowing", true);
const model = {
channel: channel,
provider: this.get('model.provider')
provider: this.get("model.provider")
};
showModal('admin-plugins-chat-edit-channel', { model: model, admin: true });
showModal("admin-plugins-chat-edit-channel", {
model: model,
admin: true
});
},
testChannel(channel) {
this.set('modalShowing', true);
showModal('admin-plugins-chat-test', { model: { channel: channel }, admin: true });
this.set("modalShowing", true);
showModal("admin-plugins-chat-test", {
model: { channel: channel },
admin: true
});
},
createRule(channel){
this.set('modalShowing', true);
createRule(channel) {
this.set("modalShowing", true);
const model = {
rule: this.store.createRecord('rule', { channel_id: channel.id }),
rule: this.store.createRecord("rule", { channel_id: channel.id }),
channel: channel,
provider: this.get('model.provider'),
groups: this.get('model.groups')
provider: this.get("model.provider"),
groups: this.get("model.groups")
};
showModal('admin-plugins-chat-edit-rule', { model: model, admin: true });
showModal("admin-plugins-chat-edit-rule", { model: model, admin: true });
},
editRule(rule, channel){
this.set('modalShowing', true);
editRule(rule, channel) {
this.set("modalShowing", true);
const model = {
rule: rule,
channel: channel,
provider: this.get('model.provider'),
groups: this.get('model.groups')
provider: this.get("model.provider"),
groups: this.get("model.groups")
};
showModal('admin-plugins-chat-edit-rule', { model: model, admin: true });
showModal("admin-plugins-chat-edit-rule", { model: model, admin: true });
},
showError(channel) {
this.set("modalShowing", true);
showModal("admin-plugins-chat-channel-error", {
model: channel,
admin: true
});
}
}
});

View File

@ -0,0 +1,4 @@
{{#d-modal-body id="chat_integration_error_modal"}}
<h4>{{i18n model.error_key}}</h4>
<pre>{{model.error_info}}</pre>
{{/d-modal-body}}

View File

@ -14,7 +14,8 @@
edit='editChannel'
test='testChannel'
createRule='createRule'
editRule='editRule'}}
editRule='editRule'
showError='showError'}}
{{/each}}
<div class="table-footer">

View File

@ -9,7 +9,7 @@
<span class='channel-title'>
{{#if channel.error_key}}
{{d-button action="showError" actionParam=channel.error_key class="delete btn-danger" icon="exclamation-triangle"}}
{{d-button action="showError" actionParam=channel class="delete btn-danger" icon="exclamation-triangle"}}
{{/if}}
{{channel-data provider=provider channel=channel}}

View File

@ -1,10 +1,9 @@
#admin-plugin-chat {
table {
margin-top:0;
margin-top: 0;
td:last-child {
white-space:nowrap;
white-space: nowrap;
}
td:not(:last-child) {
@ -18,7 +17,7 @@
div.error {
font-size: 1.1em;
font-weight:bold;
font-weight: bold;
max-width: 100%;
margin-top: 10px;
margin-bottom: 10px;
@ -33,7 +32,7 @@
div.channel-header {
background: $primary-low;
padding: 10px;
overflow:auto;
overflow: auto;
.channel-title {
font-size: 1.3em;
@ -45,7 +44,7 @@
}
div.channel-footer {
overflow:auto;
overflow: auto;
}
}
}
@ -54,7 +53,7 @@
#chat_integration_test_modal,
#chat-integration-edit-rule_modal {
table {
width:100%;
width: 100%;
tr.input td {
padding-top: 10px;
@ -83,7 +82,7 @@
.tag-chooser {
ul.select2-choices {
border: none;
background:none;
background: none;
}
margin-bottom: 0px;
@ -94,3 +93,12 @@
font-weight: bold;
}
}
#chat_integration_error_modal {
pre {
max-width: 500px;
max-height: 800px;
overflow: scroll;
background: $primary-low;
}
}

View File

@ -9,7 +9,7 @@ en:
settings: "Settings"
no_providers: "You need to enable some providers in the plugin settings"
channels_with_errors: "Some channels for this provider failed last time messages were sent. Click the error icon(s) to learn more."
channel_exception: "An unknown error occured when a message was last sent to this channel. Check the site logs for more information."
channel_exception: "An unknown error occured when a message was last sent to this channel."
group_mention_template: "Mentions of: @{{name}}"
group_message_template: "Messages to: @{{name}}"
choose_group: "(choose a group)"

View File

@ -4,7 +4,6 @@ en:
chat_integration_discourse_username: 'Username of user to act as when fetching content.'
chat_integration_delay_seconds: 'Number of seconds to wait after post creation before sending chat notitifications'
#######################################
########## SLACK SETTINGS #############
#######################################
@ -93,6 +92,8 @@ en:
group_mention_template: "mentions of: @%{name}"
group_message_template: "messages to: @%{name}"
admin_error: "Some chat integration channels have errors. Visit <a href='/admin/plugins/chat'>the chat integration section</a> to find out more."
provider:
#######################################

View File

@ -22,5 +22,13 @@ after_initialize do
add_admin_route 'chat_integration.menu_title', 'chat'
AdminDashboardData.add_problem_check do
error = false;
DiscourseChat::Channel.find_each do |channel|
error = true unless channel.error_key.blank?
end
I18n.t("chat_integration.admin_error") if error
end
DiscourseChat::Provider.mount_engines
end