Report errors to server

This commit is contained in:
jude 2023-06-20 13:13:26 +01:00
parent 9d8622f418
commit 1519474f93
10 changed files with 92 additions and 18 deletions

View File

@ -2,6 +2,7 @@ pub(crate) mod pager;
use std::io::Cursor;
use base64::{engine::general_purpose, Engine};
use chrono_tz::Tz;
use log::warn;
use poise::{
@ -51,11 +52,12 @@ impl ComponentDataModel {
pub fn to_custom_id(&self) -> String {
let mut buf = Vec::new();
self.serialize(&mut Serializer::new(&mut buf)).unwrap();
base64::encode(buf)
general_purpose::STANDARD.encode(buf)
}
pub fn from_custom_id(data: &String) -> Self {
let buf = base64::decode(data)
let buf = general_purpose::STANDARD
.decode(data)
.map_err(|e| format!("Could not decode `custom_id' {}: {:?}", data, e))
.unwrap();
let cur = Cursor::new(buf);

View File

@ -116,7 +116,8 @@ pub async fn initialize(
routes::cookies,
routes::privacy,
routes::terms,
routes::return_to_same_site
routes::return_to_same_site,
routes::report::report_error,
],
)
.mount(

View File

@ -10,9 +10,12 @@ use serenity::{
};
use sqlx::{MySql, Pool};
use crate::routes::dashboard::{
create_reminder, generate_uid, ImportBody, JsonResult, Reminder, ReminderCsv,
ReminderTemplateCsv, TodoCsv,
use crate::routes::{
dashboard::{
create_reminder, generate_uid, ImportBody, Reminder, ReminderCsv, ReminderTemplateCsv,
TodoCsv,
},
JsonResult,
};
#[get("/api/guild/<id>/export/reminders")]

View File

@ -23,9 +23,12 @@ use crate::{
MAX_EMBED_FOOTER_LENGTH, MAX_EMBED_TITLE_LENGTH, MAX_URL_LENGTH, MAX_USERNAME_LENGTH,
MIN_INTERVAL,
},
routes::dashboard::{
create_database_channel, create_reminder, template_name_default, DeleteReminder,
DeleteReminderTemplate, JsonResult, PatchReminder, Reminder, ReminderTemplate,
routes::{
dashboard::{
create_database_channel, create_reminder, template_name_default, DeleteReminder,
DeleteReminderTemplate, PatchReminder, Reminder, ReminderTemplate,
},
JsonResult,
},
};

View File

@ -2,11 +2,7 @@ use std::collections::HashMap;
use chrono::{naive::NaiveDateTime, Utc};
use rand::{rngs::OsRng, seq::IteratorRandom};
use rocket::{
http::CookieJar,
response::Redirect,
serde::json::{json, Value as JsonValue},
};
use rocket::{http::CookieJar, response::Redirect, serde::json::json};
use rocket_dyn_templates::Template;
use serde::{Deserialize, Deserializer, Serialize};
use serenity::{
@ -24,6 +20,7 @@ use crate::{
MAX_EMBED_FIELD_VALUE_LENGTH, MAX_EMBED_FOOTER_LENGTH, MAX_EMBED_TITLE_LENGTH,
MAX_URL_LENGTH, MAX_USERNAME_LENGTH, MIN_INTERVAL,
},
routes::JsonResult,
Database, Error,
};
@ -31,7 +28,6 @@ pub mod export;
pub mod guild;
pub mod user;
pub type JsonResult = Result<JsonValue, JsonValue>;
type Unset<T> = Option<T>;
fn name_default() -> String {

View File

@ -1,11 +1,14 @@
pub mod dashboard;
pub mod login;
pub mod report;
use std::collections::HashMap;
use rocket::request::FlashMessage;
use rocket::{request::FlashMessage, serde::json::Value as JsonValue};
use rocket_dyn_templates::Template;
pub type JsonResult = Result<JsonValue, JsonValue>;
#[get("/")]
pub async fn index(flash: Option<FlashMessage<'_>>) -> Template {
let mut map: HashMap<&str, String> = HashMap::new();

48
web/src/routes/report.rs Normal file
View File

@ -0,0 +1,48 @@
use rocket::{
http::CookieJar,
serde::{
json::{json, Json},
Deserialize,
},
};
use crate::routes::JsonResult;
#[derive(Deserialize)]
pub struct ClientError {
#[serde(rename = "reporterId")]
reporter_id: String,
url: String,
#[serde(rename = "relativeTimestamp")]
relative_timestamp: i64,
#[serde(rename = "errorMessage")]
error_message: String,
#[serde(rename = "errorLine")]
error_line: u64,
#[serde(rename = "errorFile")]
error_file: String,
#[serde(rename = "errorType")]
error_type: String,
}
#[post("/report", data = "<client_error>")]
pub async fn report_error(cookies: &CookieJar<'_>, client_error: Json<ClientError>) -> JsonResult {
if let Some(user_id) = cookies.get_private("userid") {
error!(
"User {} reports a client-side error.
{}, {}:{} at {}ms
{}: {}
Chain: {}",
user_id,
client_error.url,
client_error.error_file,
client_error.error_line,
client_error.relative_timestamp,
client_error.error_type,
client_error.error_message,
client_error.reporter_id
);
}
Ok(json!({}))
}

View File

@ -3,12 +3,12 @@
"short_name": "",
"icons": [
{
"src": "/android-chrome-192x192.png",
"src": "/static/favicon/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"src": "/static/favicon/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}

16
web/static/js/reporter.js Normal file
View File

@ -0,0 +1,16 @@
const REPORTER_ID = crypto.randomUUID();
window.addEventListener("error", async (ev) => {
await fetch("/report", {
method: "POST",
body: JSON.stringify({
reporterId: REPORTER_ID,
url: window.location.href,
relativeTimestamp: ev.timeStamp,
errorMessage: ev.message,
errorLine: ev.lineno,
errorFile: ev.filename,
errorType: ev.type,
}),
});
});

View File

@ -1,6 +1,8 @@
<!DOCTYPE html>
<html lang="EN">
<head>
<script src="/static/js/reporter.js" type="application/javascript"></script>
<meta name="description" content="The most powerful Discord Reminders Bot">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">