mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-19 04:57:51 +00:00
Update from master
This commit is contained in:
commit
491eb86451
@ -52,6 +52,7 @@
|
|||||||
"@types/jest": "^26.0.3",
|
"@types/jest": "^26.0.3",
|
||||||
"@types/mocha": "^7.0.2",
|
"@types/mocha": "^7.0.2",
|
||||||
"angular-draggable-droppable": "^4.5.1",
|
"angular-draggable-droppable": "^4.5.1",
|
||||||
|
"@sentry/browser": "^5.18.0",
|
||||||
"angular-persistence": "^1.0.1",
|
"angular-persistence": "^1.0.1",
|
||||||
"angular-resizable-element": "^3.3.2",
|
"angular-resizable-element": "^3.3.2",
|
||||||
"angular2-draggable": "^2.3.2",
|
"angular2-draggable": "^2.3.2",
|
||||||
@ -72,7 +73,6 @@
|
|||||||
"ngx-electron": "^2.1.1",
|
"ngx-electron": "^2.1.1",
|
||||||
"node-fetch": "^2.6.0",
|
"node-fetch": "^2.6.0",
|
||||||
"notosans-fontface": "1.1.0",
|
"notosans-fontface": "1.1.0",
|
||||||
"raven-js": "^3.27.2",
|
|
||||||
"rxjs": "^6.5.5",
|
"rxjs": "^6.5.5",
|
||||||
"rxjs-compat": "^6.5.5",
|
"rxjs-compat": "^6.5.5",
|
||||||
"save-html-as-image": "^1.3.3",
|
"save-html-as-image": "^1.3.3",
|
||||||
|
@ -277,13 +277,11 @@ def build_command(arguments):
|
|||||||
]
|
]
|
||||||
|
|
||||||
excludes = [
|
excludes = [
|
||||||
"raven.deprecation", # reported problem in raven package (6.4.0)
|
|
||||||
"distutils", # issue on macOS
|
"distutils", # issue on macOS
|
||||||
"tkinter", # issue on Windows
|
"tkinter", # issue on Windows
|
||||||
]
|
]
|
||||||
|
|
||||||
packages = [
|
packages = [
|
||||||
"raven",
|
|
||||||
"psutil",
|
"psutil",
|
||||||
"asyncio",
|
"asyncio",
|
||||||
"packaging", # needed for linux
|
"packaging", # needed for linux
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import * as Raven from 'raven-js';
|
|
||||||
import { BrowserModule, Title } from '@angular/platform-browser';
|
import { BrowserModule, Title } from '@angular/platform-browser';
|
||||||
import { NgModule, ErrorHandler } from '@angular/core';
|
import { NgModule, ErrorHandler } from '@angular/core';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
@ -64,7 +63,6 @@ import { ProgressService } from './common/progress/progress.service';
|
|||||||
import { version } from './version';
|
import { version } from './version';
|
||||||
import { ToasterErrorHandler } from './common/error-handlers/toaster-error-handler';
|
import { ToasterErrorHandler } from './common/error-handlers/toaster-error-handler';
|
||||||
import { environment } from '../environments/environment';
|
import { environment } from '../environments/environment';
|
||||||
import { RavenState } from './common/error-handlers/raven-state-communicator';
|
|
||||||
import { ServerDiscoveryComponent } from './components/servers/server-discovery/server-discovery.component';
|
import { ServerDiscoveryComponent } from './components/servers/server-discovery/server-discovery.component';
|
||||||
import { ServerDatabase } from './services/server.database';
|
import { ServerDatabase } from './services/server.database';
|
||||||
import { CreateSnapshotDialogComponent } from './components/snapshots/create-snapshot-dialog/create-snapshot-dialog.component';
|
import { CreateSnapshotDialogComponent } from './components/snapshots/create-snapshot-dialog/create-snapshot-dialog.component';
|
||||||
@ -281,15 +279,6 @@ import { ChangeHostnameActionComponent } from './components/project-map/context-
|
|||||||
import { ChangeHostnameDialogComponent } from './components/project-map/change-hostname-dialog/change-hostname-dialog.component';
|
import { ChangeHostnameDialogComponent } from './components/project-map/change-hostname-dialog/change-hostname-dialog.component';
|
||||||
import { ApplianceInfoDialogComponent } from './components/project-map/new-template-dialog/appliance-info-dialog/appliance-info-dialog.component';
|
import { ApplianceInfoDialogComponent } from './components/project-map/new-template-dialog/appliance-info-dialog/appliance-info-dialog.component';
|
||||||
|
|
||||||
if (environment.production) {
|
|
||||||
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
|
|
||||||
shouldSendCallback: () => {
|
|
||||||
return RavenState.shouldSend;
|
|
||||||
},
|
|
||||||
release: version
|
|
||||||
}).install();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
import { PersistenceService } from 'angular-persistence';
|
|
||||||
|
|
||||||
import { SettingsService } from '../../services/settings.service';
|
|
||||||
import { RavenErrorHandler } from './raven-error-handler';
|
|
||||||
import { environment } from '../../../environments/environment';
|
|
||||||
|
|
||||||
describe('RavenErrorHandler', () => {
|
|
||||||
let handler: RavenErrorHandler;
|
|
||||||
let settingsService: SettingsService;
|
|
||||||
const inProductionOriginal = environment.production;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
providers: [SettingsService, PersistenceService, RavenErrorHandler]
|
|
||||||
});
|
|
||||||
|
|
||||||
settingsService = TestBed.get(SettingsService);
|
|
||||||
handler = TestBed.get(RavenErrorHandler);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
environment.production = inProductionOriginal;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(handler).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle error', () => {
|
|
||||||
settingsService.set('crash_reports', true);
|
|
||||||
environment.production = true;
|
|
||||||
expect(handler.shouldSend()).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not handle when crash reports are disabled', () => {
|
|
||||||
settingsService.set('crash_reports', false);
|
|
||||||
expect(handler.shouldSend()).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,20 +0,0 @@
|
|||||||
import { ErrorHandler, Inject, Injector } from '@angular/core';
|
|
||||||
|
|
||||||
import { SettingsService } from '../../services/settings.service';
|
|
||||||
import { environment } from '../../../environments/environment';
|
|
||||||
import { RavenState } from './raven-state-communicator';
|
|
||||||
|
|
||||||
export class RavenErrorHandler implements ErrorHandler {
|
|
||||||
constructor(@Inject(Injector) protected injector: Injector) {}
|
|
||||||
|
|
||||||
handleError(err: any): void {
|
|
||||||
RavenState.shouldSend = this.shouldSend();
|
|
||||||
|
|
||||||
console.error(err.originalError || err);
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldSend() {
|
|
||||||
const settingsService: SettingsService = this.injector.get(SettingsService);
|
|
||||||
return environment.production && settingsService.get('crash_reports');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
export class RavenStateCommunicator {
|
|
||||||
public shouldSend = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
export var RavenState = new RavenStateCommunicator();
|
|
71
src/app/common/error-handlers/sentry-error-handler.ts
Normal file
71
src/app/common/error-handlers/sentry-error-handler.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { BrowserModule } from "@angular/platform-browser";
|
||||||
|
import { NgModule, ErrorHandler, Injectable, Injector, Inject } from "@angular/core";
|
||||||
|
import { HttpErrorResponse } from "@angular/common/http";
|
||||||
|
|
||||||
|
import { environment } from "../../../environments/environment";
|
||||||
|
import { AppComponent } from "../../app.component";
|
||||||
|
|
||||||
|
import * as Sentry from "@sentry/browser";
|
||||||
|
import { BrowserOptions, init } from '@sentry/browser';
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
dsn: "https://b2b1cfd9b043491eb6b566fd8acee358@o19455.ingest.sentry.io/842726"
|
||||||
|
};
|
||||||
|
init(config as BrowserOptions);
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SentryErrorHandler implements ErrorHandler {
|
||||||
|
constructor(@Inject(Injector) protected injector: Injector) {}
|
||||||
|
|
||||||
|
extractError(error) {
|
||||||
|
// Try to unwrap zone.js error.
|
||||||
|
// https://github.com/angular/angular/blob/master/packages/core/src/util/errors.ts
|
||||||
|
if (error && error.ngOriginalError) {
|
||||||
|
error = error.ngOriginalError;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can handle messages and Error objects directly.
|
||||||
|
if (typeof error === "string" || error instanceof Error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's http module error, extract as much information from it as we can.
|
||||||
|
if (error instanceof HttpErrorResponse) {
|
||||||
|
// The `error` property of http exception can be either an `Error` object, which we can use directly...
|
||||||
|
if (error.error instanceof Error) {
|
||||||
|
return error.error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... or an`ErrorEvent`, which can provide us with the message but no stack...
|
||||||
|
if (error.error instanceof ErrorEvent) {
|
||||||
|
return error.error.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...or the request body itself, which we can use as a message instead.
|
||||||
|
if (typeof error.error === "string") {
|
||||||
|
return `Server returned code ${error.status} with body "${error.error}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't have any detailed information, fallback to the request message itself.
|
||||||
|
return error.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if there's no error, and let user decide what to do with it.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleError(error) {
|
||||||
|
let extractedError = this.extractError(error) || "Handled unknown error";
|
||||||
|
|
||||||
|
// Capture handled exception and send it to Sentry.
|
||||||
|
const eventId = Sentry.captureException(extractedError);
|
||||||
|
|
||||||
|
// When in development mode, log the error to console for immediate feedback.
|
||||||
|
if (!environment.production) {
|
||||||
|
console.error(extractedError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally show user dialog to provide details on what happened.
|
||||||
|
Sentry.showReportDialog({ eventId });
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,10 @@ import { TestBed } from '@angular/core/testing';
|
|||||||
import { ToasterService } from '../../services/toaster.service';
|
import { ToasterService } from '../../services/toaster.service';
|
||||||
import { MockedToasterService } from '../../services/toaster.service.spec';
|
import { MockedToasterService } from '../../services/toaster.service.spec';
|
||||||
import { ToasterErrorHandler } from './toaster-error-handler';
|
import { ToasterErrorHandler } from './toaster-error-handler';
|
||||||
import { RavenErrorHandler } from './raven-error-handler';
|
|
||||||
import { SettingsService } from '../../services/settings.service';
|
import { SettingsService } from '../../services/settings.service';
|
||||||
import { MockedSettingsService } from '../../services/settings.service.spec';
|
import { MockedSettingsService } from '../../services/settings.service.spec';
|
||||||
import { Injector } from '@angular/core';
|
import { Injector } from '@angular/core';
|
||||||
|
import { SentryErrorHandler } from './sentry-error-handler';
|
||||||
|
|
||||||
class MockedToasterErrorHandler extends ToasterErrorHandler {
|
class MockedToasterErrorHandler extends ToasterErrorHandler {
|
||||||
handleError(err: any): void {
|
handleError(err: any): void {
|
||||||
@ -23,7 +23,7 @@ describe('ToasterErrorHandler', () => {
|
|||||||
providers: [
|
providers: [
|
||||||
{ provide: ToasterService, useClass: MockedToasterService },
|
{ provide: ToasterService, useClass: MockedToasterService },
|
||||||
{ provide: SettingsService, useClass: MockedSettingsService },
|
{ provide: SettingsService, useClass: MockedSettingsService },
|
||||||
RavenErrorHandler,
|
SentryErrorHandler,
|
||||||
ToasterErrorHandler
|
ToasterErrorHandler
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { RavenErrorHandler } from './raven-error-handler';
|
|
||||||
import { ToasterService } from '../../services/toaster.service';
|
import { ToasterService } from '../../services/toaster.service';
|
||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
import { SentryErrorHandler } from './sentry-error-handler';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ToasterErrorHandler extends RavenErrorHandler {
|
export class ToasterErrorHandler extends SentryErrorHandler {
|
||||||
handleError(err: any): void {
|
handleError(err: any): void {
|
||||||
super.handleError(err);
|
super.handleError(err);
|
||||||
if (!err) return;
|
if (!err) return;
|
||||||
|
@ -8800,11 +8800,6 @@ range-parser@^1.2.1, range-parser@~1.2.1:
|
|||||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
||||||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
||||||
|
|
||||||
raven-js@^3.27.2:
|
|
||||||
version "3.27.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.27.2.tgz#6c33df952026cd73820aa999122b7b7737a66775"
|
|
||||||
integrity sha512-mFWQcXnhRFEQe5HeFroPaEghlnqy7F5E2J3Fsab189ondqUzcjwSVi7el7F36cr6PvQYXoZ1P2F5CSF2/azeMQ==
|
|
||||||
|
|
||||||
raw-body@2.4.0:
|
raw-body@2.4.0:
|
||||||
version "2.4.0"
|
version "2.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
|
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
|
||||||
|
Loading…
Reference in New Issue
Block a user