mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 19:21:50 +00:00
App: Add error page (#52453)
This commit is contained in:
parent
580a690d4f
commit
91a99340b0
@ -1,4 +1,5 @@
|
||||
import * as fs from 'fs'
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import * as esbuild from 'esbuild'
|
||||
|
||||
@ -10,6 +11,19 @@ import {
|
||||
} from '@sourcegraph/build-config'
|
||||
import { isDefined } from '@sourcegraph/common'
|
||||
|
||||
async function copyStaticFiles(sourceDir: string, destinationDir: string): Promise<void> {
|
||||
await fs.mkdir(destinationDir, { recursive: true })
|
||||
|
||||
const files = await fs.readdir(sourceDir)
|
||||
|
||||
for (const file of files) {
|
||||
const sourceFile = path.join(sourceDir, file)
|
||||
const destinationFile = path.join(destinationDir, file)
|
||||
await fs.copyFile(sourceFile, destinationFile)
|
||||
console.info(`${sourceFile} written to ${destinationFile}`)
|
||||
}
|
||||
}
|
||||
|
||||
export const BUILD_OPTIONS: esbuild.BuildOptions = {
|
||||
entryPoints: ['src/app-shell.tsx'],
|
||||
bundle: true,
|
||||
@ -44,14 +58,13 @@ export const build = async (): Promise<void> => {
|
||||
outdir: 'dist/scripts/',
|
||||
metafile: Boolean(metafile),
|
||||
})
|
||||
|
||||
if (metafile) {
|
||||
fs.writeFileSync(metafile, JSON.stringify(result.metafile), 'utf-8')
|
||||
await fs.writeFile(metafile, JSON.stringify(result.metafile), 'utf-8')
|
||||
}
|
||||
|
||||
if (result.errors.length === 0) {
|
||||
const content = await fs.promises.readFile('index.html', 'utf8')
|
||||
fs.writeFileSync('dist/index.html', content)
|
||||
console.info('index.html written to dist/index.html')
|
||||
await copyStaticFiles('static', 'dist')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
64
client/app-shell/static/error.html
Normal file
64
client/app-shell/static/error.html
Normal file
@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
color: #14171f;
|
||||
font-size: 14px;
|
||||
}
|
||||
.container {
|
||||
margin: 80px auto;
|
||||
width: 300px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
color: #343a4d;
|
||||
}
|
||||
.button {
|
||||
width: 100%;
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
background-color: #0b70db;
|
||||
color: white;
|
||||
text-align: center;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
margin: 16px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.button.button-secondary {
|
||||
background-color: #DBE2F0;
|
||||
color: #343A4D;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<img src="./error.svg" />
|
||||
<h1>Oops, something went wrong.</h1>
|
||||
<p>Here are some troubleshooting options:</p>
|
||||
<button class="button" id="show-logs-button">Show logs</button>
|
||||
<a href="https://github.com/sourcegraph/app" class="button">File an issue</a>
|
||||
<p>When filing an issue, be sure to include the logs.</p>
|
||||
<button class="button button-secondary" id="restart-button">Close and restart</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.getElementById('show-logs-button').addEventListener('click', () => {
|
||||
__TAURI__.invoke('show_logs').catch(console.error)
|
||||
})
|
||||
|
||||
document.getElementById('restart-button').addEventListener('click', () => {
|
||||
__TAURI__.invoke('restart_app').catch(console.error)
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
3
client/app-shell/static/error.svg
Normal file
3
client/app-shell/static/error.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="43" height="44" viewBox="0 0 43 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.0276 26.5353L17.1284 28.4345L19.0276 30.3336L17.1284 32.2328L15.2292 30.3336L13.3301 32.2328L11.4309 30.3336L13.3301 28.4345L11.4309 26.5353L13.3301 24.6361L15.2292 26.5353L17.1284 24.6361L19.0276 26.5353ZM29.6701 24.6361L27.7709 26.5353L25.8717 24.6361L23.9726 26.5353L25.8717 28.4345L23.9726 30.3336L25.8717 32.2328L27.7709 30.3336L29.6701 32.2328L31.5693 30.3336L29.6701 28.4345L31.5693 26.5353L29.6701 24.6361ZM41.2084 27.5386V32.9136C41.2084 33.8991 40.4022 34.7053 39.4168 34.7053H37.6251V36.497C37.6251 38.4857 36.0305 40.0803 34.0418 40.0803H8.95842C6.98758 40.0803 5.37508 38.4857 5.37508 36.497V34.7053H3.58341C2.598 34.7053 1.79175 33.8991 1.79175 32.9136V27.5386C1.79175 26.5532 2.598 25.747 3.58341 25.747H5.37508C5.37508 18.8132 10.983 13.2053 17.9167 13.2053H19.7084V10.9299C18.6334 10.3207 17.9167 9.15615 17.9167 7.83031C17.9167 5.85948 19.5292 4.24698 21.5001 4.24698C23.4709 4.24698 25.0834 5.85948 25.0834 7.83031C25.0834 9.15615 24.3668 10.3207 23.2917 10.9299V13.2053H25.0834C32.0172 13.2053 37.6251 18.8132 37.6251 25.747H39.4168C40.4022 25.747 41.2084 26.5532 41.2084 27.5386ZM37.6251 29.3303H34.0418V25.747C34.0418 20.802 30.0284 16.7886 25.0834 16.7886H17.9167C12.9717 16.7886 8.95842 20.802 8.95842 25.747V29.3303H5.37508V31.122H8.95842V36.497H34.0418V31.122H37.6251V29.3303Z" fill="#798BAF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@ -1,3 +1,4 @@
|
||||
use tauri::api::shell;
|
||||
use tauri::AppHandle;
|
||||
use tauri::Manager;
|
||||
|
||||
@ -29,3 +30,12 @@ pub fn extract_path_from_scheme_url<'a>(url: &'a str, scheme: &str) -> &'a str {
|
||||
pub fn is_scheme_url(url: &str, scheme: &str) -> bool {
|
||||
url.starts_with(scheme) && url[scheme.len()..].starts_with("://")
|
||||
}
|
||||
|
||||
pub fn show_logs(app: &AppHandle) {
|
||||
let log_dir_path = app.path_resolver().app_log_dir().unwrap();
|
||||
if let Some(log_path_str) = log_dir_path.to_str() {
|
||||
let name = &app.package_info().name;
|
||||
let combined_path = format!("{}/{}.log", log_path_str, name);
|
||||
shell::open(&app.shell_scope(), &combined_path, None).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +46,16 @@ fn reload_cody_window(app_handle: tauri::AppHandle) {
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn show_logs(app_handle: tauri::AppHandle) {
|
||||
common::show_logs(&app_handle);
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn restart_app(app_handle: tauri::AppHandle) {
|
||||
app_handle.restart();
|
||||
}
|
||||
|
||||
fn set_launch_path(url: String) {
|
||||
*LAUNCH_PATH.write().unwrap() = url;
|
||||
}
|
||||
@ -150,7 +160,14 @@ fn main() {
|
||||
// its name which may suggest that it invokes something, actually only
|
||||
// *defines* an invoke() handler and does not invoke anything during
|
||||
// setup here.)
|
||||
.invoke_handler(tauri::generate_handler![get_launch_path, app_shell_loaded, show_main_window, reload_cody_window])
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
get_launch_path,
|
||||
app_shell_loaded,
|
||||
show_main_window,
|
||||
reload_cody_window,
|
||||
show_logs,
|
||||
restart_app
|
||||
])
|
||||
.run(context)
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
@ -202,12 +219,30 @@ fn start_embedded_services(handle: &tauri::AppHandle) {
|
||||
}
|
||||
log::error!("{}", line);
|
||||
}
|
||||
CommandEvent::Error(err) => {
|
||||
show_error_screen(&app);
|
||||
log::error!("Command Error: {:#?}", err)
|
||||
}
|
||||
CommandEvent::Terminated(payload) => {
|
||||
show_error_screen(&app);
|
||||
log::error!("Command Terminated: {:#?}", payload)
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Show the error page in the main window
|
||||
fn show_error_screen(app_handle: &tauri::AppHandle) {
|
||||
app_handle
|
||||
.get_window("main")
|
||||
.unwrap()
|
||||
.eval("window.location.href = 'tauri://localhost/error.html';")
|
||||
.unwrap();
|
||||
show_window(app_handle, "main");
|
||||
}
|
||||
|
||||
fn get_sourcegraph_args(app_handle: &tauri::AppHandle) -> Vec<String> {
|
||||
let data_dir = app_handle.path_resolver().app_data_dir();
|
||||
let cache_dir = app_handle.path_resolver().app_cache_dir();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use crate::cody::init_cody_window;
|
||||
use crate::common::show_window;
|
||||
use crate::common::{show_logs, show_window};
|
||||
use tauri::api::shell;
|
||||
use tauri::{
|
||||
AppHandle, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu,
|
||||
@ -12,10 +12,7 @@ pub fn create_system_tray() -> SystemTray {
|
||||
|
||||
fn create_system_tray_menu() -> SystemTrayMenu {
|
||||
SystemTrayMenu::new()
|
||||
.add_item(CustomMenuItem::new(
|
||||
"open".to_string(),
|
||||
"Open Sourcegraph",
|
||||
))
|
||||
.add_item(CustomMenuItem::new("open".to_string(), "Open Sourcegraph"))
|
||||
.add_item(CustomMenuItem::new("cody".to_string(), "Show Cody"))
|
||||
.add_native_item(SystemTrayMenuItem::Separator)
|
||||
.add_item(
|
||||
@ -52,14 +49,8 @@ pub fn on_system_tray_event(app: &AppHandle, event: SystemTrayEvent) {
|
||||
window.eval("window.location.href = '/settings'").unwrap();
|
||||
show_window(app, "main");
|
||||
}
|
||||
"troubleshoot" => {
|
||||
let log_dir_path = app.path_resolver().app_log_dir().unwrap();
|
||||
if let Some(log_path_str) = log_dir_path.to_str() {
|
||||
let name = &app.package_info().name;
|
||||
let combined_path = format!("{}/{}.log", log_path_str, name);
|
||||
shell::open(&app.shell_scope(), &combined_path, None).unwrap()
|
||||
}
|
||||
}
|
||||
"troubleshoot" => show_logs(app),
|
||||
|
||||
"about" => {
|
||||
shell::open(&app.shell_scope(), "https://about.sourcegraph.com", None).unwrap()
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user