mirror of
https://github.com/google/nomulus.git
synced 2025-07-23 19:20:44 +02:00
Refine error handling in RequestHandler and the console slightly (#2177)
If we don't explicitly handle random unexpected exceptions, the error that the front end receives includes a big ole stacktrace, which is unhelpful for regular users and possibly bad to expose. Instead, we should provide a vague "something went wrong" message. Separately, we can create a default SnackBar options and use that (we want it longer than 1.5 seconds because that's pretty short).
This commit is contained in:
parent
36bd508bf9
commit
a63916b08e
8 changed files with 37 additions and 18 deletions
|
@ -48,6 +48,7 @@ import { DomainsWidgetComponent } from './home/widgets/domains-widget.component'
|
||||||
import { SettingsWidgetComponent } from './home/widgets/settings-widget.component';
|
import { SettingsWidgetComponent } from './home/widgets/settings-widget.component';
|
||||||
import { UserDataService } from './shared/services/userData.service';
|
import { UserDataService } from './shared/services/userData.service';
|
||||||
import WhoisComponent from './settings/whois/whois.component';
|
import WhoisComponent from './settings/whois/whois.component';
|
||||||
|
import { SnackBarModule } from './snackbar.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -79,6 +80,7 @@ import WhoisComponent from './settings/whois/whois.component';
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
MaterialModule,
|
MaterialModule,
|
||||||
|
SnackBarModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
BackendService,
|
BackendService,
|
||||||
|
|
|
@ -89,8 +89,6 @@ export class RegistrarService implements GlobalLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingTimeout() {
|
loadingTimeout() {
|
||||||
this._snackBar.open('Timeout loading registrars', undefined, {
|
this._snackBar.open('Timeout loading registrars');
|
||||||
duration: 1500,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,9 +129,7 @@ export class ContactDetailsDialogComponent {
|
||||||
operationObservable.subscribe({
|
operationObservable.subscribe({
|
||||||
complete: this.onCloseCallback.bind(this),
|
complete: this.onCloseCallback.bind(this),
|
||||||
error: (err: HttpErrorResponse) => {
|
error: (err: HttpErrorResponse) => {
|
||||||
this._snackBar.open(err.error, undefined, {
|
this._snackBar.open(err.error);
|
||||||
duration: 1500,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -175,9 +173,7 @@ export default class ContactComponent {
|
||||||
if (confirm(`Please confirm contact ${contact.name} delete`)) {
|
if (confirm(`Please confirm contact ${contact.name} delete`)) {
|
||||||
this.contactService.deleteContact(contact).subscribe({
|
this.contactService.deleteContact(contact).subscribe({
|
||||||
error: (err: HttpErrorResponse) => {
|
error: (err: HttpErrorResponse) => {
|
||||||
this._snackBar.open(err.error, undefined, {
|
this._snackBar.open(err.error);
|
||||||
duration: 1500,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,9 +64,7 @@ export default class SecurityComponent {
|
||||||
this.resetDataSource();
|
this.resetDataSource();
|
||||||
},
|
},
|
||||||
error: (err: HttpErrorResponse) => {
|
error: (err: HttpErrorResponse) => {
|
||||||
this._snackBar.open(err.error, undefined, {
|
this._snackBar.open(err.error);
|
||||||
duration: 1500,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.cancel();
|
this.cancel();
|
||||||
|
|
|
@ -61,9 +61,8 @@ export default class WhoisComponent {
|
||||||
this.resetDataSource();
|
this.resetDataSource();
|
||||||
},
|
},
|
||||||
error: (err: HttpErrorResponse) => {
|
error: (err: HttpErrorResponse) => {
|
||||||
this._snackBar.open(err.error, undefined, {
|
this._snackBar.open(err.error);
|
||||||
duration: 1500,
|
this.loading = false;
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.cancel();
|
this.cancel();
|
||||||
|
|
|
@ -49,8 +49,6 @@ export class UserDataService implements GlobalLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingTimeout() {
|
loadingTimeout() {
|
||||||
this._snackBar.open('Timeout loading user data', undefined, {
|
this._snackBar.open('Timeout loading user data');
|
||||||
duration: 1500,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
24
console-webapp/src/app/snackbar.module.ts
Normal file
24
console-webapp/src/app/snackbar.module.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material/snack-bar';
|
||||||
|
|
||||||
|
/** Provides a default set of options for the snack bar. */
|
||||||
|
@NgModule({
|
||||||
|
providers: [
|
||||||
|
{ provide: MAT_SNACK_BAR_DEFAULT_OPTIONS, useValue: { duration: 5000 } },
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class SnackBarModule {}
|
|
@ -17,6 +17,7 @@ package google.registry.request;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
|
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_METHOD_NOT_ALLOWED;
|
import static javax.servlet.http.HttpServletResponse.SC_METHOD_NOT_ALLOWED;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||||
|
|
||||||
|
@ -162,6 +163,9 @@ public class RequestHandler<C> {
|
||||||
} catch (HttpException e) {
|
} catch (HttpException e) {
|
||||||
e.send(rsp);
|
e.send(rsp);
|
||||||
success = false;
|
success = false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
rsp.setStatus(SC_INTERNAL_SERVER_ERROR);
|
||||||
|
rsp.getWriter().write("Internal server error, please try again later");
|
||||||
} finally {
|
} finally {
|
||||||
requestMetrics.record(
|
requestMetrics.record(
|
||||||
new Duration(startTime, clock.nowUtc()),
|
new Duration(startTime, clock.nowUtc()),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue