diff options
author | Martin Stockhammer <martin_s@apache.org> | 2020-12-24 10:37:55 +0100 |
---|---|---|
committer | Martin Stockhammer <martin_s@apache.org> | 2020-12-24 10:37:55 +0100 |
commit | cb0e4d19d78956b536c62772ae042c281d07ad9f (patch) | |
tree | 460f837cdd12d6ece1dac0d1beabbf1770582434 /archiva-modules/archiva-web/archiva-webapp | |
parent | 7744b086d7f71b67f436c0f617d262b2ae91c8f6 (diff) | |
download | archiva-cb0e4d19d78956b536c62772ae042c281d07ad9f.tar.gz archiva-cb0e4d19d78956b536c62772ae042c281d07ad9f.zip |
Improving error handling
Diffstat (limited to 'archiva-modules/archiva-web/archiva-webapp')
10 files changed, 127 insertions, 63 deletions
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/app-notification.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/app-notification.ts index 787762b0a..ae1b0a45a 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/app-notification.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/app-notification.ts @@ -33,7 +33,6 @@ export class AppNotification { this.header = header; this.body = body; this.timestamp = timestamp; - console.log("Options " + JSON.stringify(options)); if (options.classname) { this.classname = options.classname; } @@ -49,7 +48,7 @@ export class AppNotification { } public toString(): string { - return this.origin + ',classname:' + this.classname + ", delay:" + this.delay +", context: "+JSON.stringify(this.contextData); + return this.origin + ',classname:' + this.classname + ", delay:" + this.delay ; } } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts index 321557b85..7654ee929 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts @@ -16,16 +16,7 @@ * under the License. */ -import { - AfterContentInit, - ChangeDetectorRef, - Component, - EventEmitter, - OnInit, - Output, - TemplateRef, - ViewChild -} from '@angular/core'; +import {AfterContentInit, Component, EventEmitter, OnInit, Output, ViewChild} from '@angular/core'; import {ActivatedRoute} from "@angular/router"; import {FormBuilder, Validators} from "@angular/forms"; import {RoleService} from "@app/services/role.service"; @@ -42,6 +33,7 @@ import {UserService} from "@app/services/user.service"; import {UserInfo} from '@app/model/user-info'; import {HttpResponse} from "@angular/common/http"; import {PaginatedEntitiesComponent} from "@app/modules/shared/paginated-entities/paginated-entities.component"; +import {ToastService} from "@app/services/toast.service"; @Component({ selector: 'app-manage-roles-edit', @@ -73,7 +65,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements roleIdEvent: EventEmitter<string> = new EventEmitter<string>(true); constructor(private route: ActivatedRoute, public roleService: RoleService, private userService: UserService, - public fb: FormBuilder, private changeDetect : ChangeDetectorRef) { + public fb: FormBuilder, private toastService: ToastService) { super(fb); super.init(fb.group({ id: [''], @@ -151,7 +143,9 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements } else { return this.roleService.getRole(myId).pipe(tap(role => { this.roleCache.set(role.id, role); - }),catchError(() => of(this.createRole(id)))); + }),catchError((error : ErrorResult) => { + this.showError(error, "roles.edit.errors.retrieveFailed") + return of(this.createRole(id)); })); } })); } @@ -192,6 +186,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements this.error = true; this.success = false; this.errorResult = err; + this.showError(err, 'roles.edit.errors.updateFailed',{'role_id':role.id}) return []; }) ).subscribe(roleInfo => { @@ -199,6 +194,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements this.success = true; this.errorResult = null; this.result = roleInfo; + this.showSuccess('roles.edit.success.updated',{'role_id':role.id}) this.editMode = false; }); @@ -233,6 +229,17 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements return item.user_id; } + showError(err: ErrorResult, errorKey:string, params:any={}) : void { + let message = err.error_messages.length>0?err.error_messages[0]:'' + params['message']=message + this.toastService.showErrorByKey('manage-roles-edit',errorKey,params) + } + + showSuccess(successKey:string, params:any={}) : void { + console.log("Success " + successKey + " - " + JSON.stringify(params)); + this.toastService.showSuccessByKey('manage-roles-edit',successKey,params) + } + assignUserRole() { let userId; if (typeof(this.userSearchModel)=='string') { @@ -248,6 +255,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements this.error = true; this.success = false; this.errorResult = err; + this.showError(err, 'roles.edit.errors.assignFailed', {'role_id':this.editRole.id,'user_id':userId}) return []; }) ).subscribe((response : HttpResponse<Role>) => { @@ -256,6 +264,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements this.errorResult = null; this.result = response.body; this.roleUserComponent.changePage(1); + this.showSuccess('roles.edit.success.assign',{'role_id':this.editRole.id,'user_id':userId}) this.userSearchModel='' }); } @@ -269,6 +278,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements this.error = true; this.success = false; this.errorResult = err; + this.showError(err, 'roles.edit.errors.unassignFailed',{'role_id':this.editRole.id,'user_id':user_id}) return []; }) ).subscribe((response : HttpResponse<Role>) => { @@ -278,6 +288,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements this.errorResult = null; this.result = response.body; this.roleUserComponent.changePage(1); + this.showSuccess('roles.edit.success.unassign',{'role_id':this.editRole.id,'user_id':user_id}) } ); } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-add/manage-users-add.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-add/manage-users-add.component.html index 915c81261..c04ee50c6 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-add/manage-users-add.component.html +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-add/manage-users-add.component.html @@ -90,9 +90,6 @@ <button class="btn btn-primary" type="submit" [attr.disabled]="userForm.valid?null:true">{{'users.add.submit'|translate}}</button> </div> - <div class="form-group col-md-8"> - <button class="btn btn-primary" (click)="showMessage()">Show Message</button> - </div> <ng-template #successTmpl let-userId="user_id"> User <a [routerLink]="['/security','users','edit',userId]">{{userId}}</a> was added to the list. diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-roles/manage-users-roles.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-roles/manage-users-roles.component.ts index 1beb1f0e0..9608bba0b 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-roles/manage-users-roles.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-roles/manage-users-roles.component.ts @@ -17,16 +17,16 @@ */ import {AfterViewInit, Component, EventEmitter, OnInit, Output} from '@angular/core'; -import { Role } from '@app/model/role'; +import {Role} from '@app/model/role'; import {UserService} from "@app/services/user.service"; import {ActivatedRoute} from "@angular/router"; -import {catchError, filter, map, multicast, share, switchMap, tap} from "rxjs/operators"; +import {catchError, filter, map, share, switchMap, tap} from "rxjs/operators"; import {RoleTree} from "@app/model/role-tree"; import {RoleService} from "@app/services/role.service"; import {RoleTemplate} from "@app/model/role-template"; -import {Observable, of} from "rxjs"; +import {Observable} from "rxjs"; import {Util} from "@app/modules/shared/shared.module"; -import { RoleResult } from './role-result'; +import {RoleResult} from './role-result'; import {fromArray} from "rxjs/internal/observable/fromArray"; import {ErrorResult} from "@app/model/error-result"; import {HttpResponse} from "@angular/common/http"; diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts index 8e2e16650..f7d2188a8 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts @@ -16,26 +16,13 @@ * under the License. */ -import {AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; -import {concat, merge, Observable, of, pipe, Subject} from "rxjs"; -import { - concatAll, - debounceTime, - delay, - distinctUntilChanged, - filter, - map, - mergeMap, - pluck, - share, - startWith, - switchMap, - tap -} from "rxjs/operators"; -import {EntityService} from "../../../model/entity-service"; -import {FieldToggle} from "../../../model/field-toggle"; -import {PageQuery} from "@app/modules/shared/model/page-query"; -import { LoadingValue } from '../shared.module'; +import {AfterViewInit, Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {concat, merge, Observable, of, Subject} from "rxjs"; +import {debounceTime, distinctUntilChanged, filter, map, pluck, startWith, switchMap} from "rxjs/operators"; +import {EntityService} from "@app/model/entity-service"; +import {FieldToggle} from "@app/model/field-toggle"; +import {PageQuery} from "../model/page-query"; +import {LoadingValue} from '../model/loading-value'; import {PagedResult} from "@app/model/paged-result"; diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/toast/toast.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/toast/toast.component.ts index 0813f6c7b..ff6a03313 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/toast/toast.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/toast/toast.component.ts @@ -41,7 +41,7 @@ import {AppNotification} from "@app/model/app-notification"; <ng-template #text>{{ toast.body }}</ng-template> </ngb-toast> `, - styles: [".ngb-toasts{margin:.5em;padding:0.5em;position:fixed;right:2px;top:2px;z-index:1200}" + styles: [".ngb-toasts{margin:.5em;padding:0.5em;position:fixed;right:2px;top:20px;z-index:1200}" ], host: {'[class.ngb-toasts]': 'true'} }) diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/with-loading.pipe.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/with-loading.pipe.ts index 8de45eda5..dbb9cd04b 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/with-loading.pipe.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/with-loading.pipe.ts @@ -16,10 +16,10 @@ * under the License. */ -import { Pipe, PipeTransform } from '@angular/core'; -import {concat, isObservable, of } from 'rxjs'; -import {catchError, map, startWith, tap } from 'rxjs/operators'; -import {LoadingValue} from "@app/modules/shared/shared.module"; +import {Pipe, PipeTransform} from '@angular/core'; +import {isObservable, of} from 'rxjs'; +import {catchError, map, startWith} from 'rxjs/operators'; +import {LoadingValue} from "@app/modules/shared/model/loading-value"; @Pipe({ name: 'withLoading' diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/role.service.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/role.service.ts index e5b7e3954..5886c8ae7 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/role.service.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/role.service.ts @@ -19,13 +19,14 @@ import { Injectable } from '@angular/core'; import {ArchivaRequestService} from "@app/services/archiva-request.service"; import {RoleTemplate} from "@app/model/role-template"; -import { Observable } from 'rxjs'; +import {Observable, throwError} from 'rxjs'; import { Role } from '@app/model/role'; -import {HttpResponse} from "@angular/common/http"; +import {HttpErrorResponse, HttpResponse} from "@angular/common/http"; import {PagedResult} from "@app/model/paged-result"; import {UserInfo} from "@app/model/user-info"; import {RoleUpdate} from "@app/model/role-update"; import { User } from '@app/model/user'; +import {catchError} from "rxjs/operators"; @Injectable({ providedIn: 'root' @@ -35,15 +36,24 @@ export class RoleService { constructor(private rest: ArchivaRequestService) { } public getTemplates() : Observable<RoleTemplate[]> { - return this.rest.executeRestCall("get", "redback", "roles/templates", null); + return this.rest.executeRestCall<RoleTemplate[]>("get", "redback", "roles/templates", null).pipe( + catchError((error: HttpErrorResponse) => { + return throwError(this.rest.getTranslatedErrorResult(error)); + })); } public assignRole(roleId, userId) : Observable<HttpResponse<Role>> { - return this.rest.executeResponseCall<Role>("put", "redback", "roles/" + roleId + "/user/" + userId, null); + return this.rest.executeResponseCall<Role>("put", "redback", "roles/" + roleId + "/user/" + userId, null).pipe( + catchError((error: HttpErrorResponse) => { + return throwError(this.rest.getTranslatedErrorResult(error)); + })); } public unAssignRole(roleId, userId) : Observable<HttpResponse<Role>> { - return this.rest.executeResponseCall<Role>("delete", "redback", "roles/" + roleId + "/user/" + userId, null); + return this.rest.executeResponseCall<Role>("delete", "redback", "roles/" + roleId + "/user/" + userId, null).pipe( + catchError((error: HttpErrorResponse) => { + return throwError(this.rest.getTranslatedErrorResult(error)); + })); } public query(searchTerm: string, offset: number = 0, limit: number = 10, orderBy: string[] = ['id'], order: string = 'asc'): Observable<PagedResult<Role>> { @@ -59,7 +69,10 @@ export class RoleService { 'limit': limit, 'orderBy': orderBy, 'order': order - }); + }).pipe( + catchError((error: HttpErrorResponse) => { + return throwError(this.rest.getTranslatedErrorResult(error)); + })); } public queryAssignedUsers(roleId: string, @@ -77,7 +90,10 @@ export class RoleService { 'limit': limit, 'orderBy': orderBy, 'order': order - }); + }).pipe( + catchError((error: HttpErrorResponse) => { + return throwError(this.rest.getTranslatedErrorResult(error)); + })); } /** @@ -108,7 +124,10 @@ export class RoleService { 'limit': limit, 'orderBy': orderBy, 'order': order - }); + }).pipe( + catchError((error: HttpErrorResponse) => { + return throwError(this.rest.getTranslatedErrorResult(error)); + })); } public queryUnAssignedUsers(roleId: string, @@ -126,16 +145,25 @@ export class RoleService { 'limit': limit, 'orderBy': orderBy, 'order': order - }); + }).pipe( + catchError((error: HttpErrorResponse) => { + return throwError(this.rest.getTranslatedErrorResult(error)); + })); } public getRole(roleId:string) : Observable<Role> { - return this.rest.executeRestCall("get", "redback", "roles/" + roleId, null); + return this.rest.executeRestCall<Role>("get", "redback", "roles/" + roleId, null).pipe( + catchError((error: HttpErrorResponse) => { + return throwError(this.rest.getTranslatedErrorResult(error)); + })); } public updateRole(role:RoleUpdate) : Observable<Role> { - return this.rest.executeRestCall("patch", "redback", "roles/" + role.id, role); + return this.rest.executeRestCall<Role>("patch", "redback", "roles/" + role.id, role).pipe( + catchError((error: HttpErrorResponse) => { + return throwError(this.rest.getTranslatedErrorResult(error)); + })); } } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/toast.service.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/toast.service.ts index b168a0f51..1b1a934aa 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/toast.service.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/toast.service.ts @@ -19,6 +19,7 @@ import { Injectable, TemplateRef } from '@angular/core'; import {AppNotification} from "@app/model/app-notification"; import {not} from "rxjs/internal-compatibility"; +import {TranslateService} from "@ngx-translate/core"; @Injectable({ providedIn: 'root' @@ -30,9 +31,9 @@ export class ToastService { toasts:AppNotification[]=[] toastHistory:AppNotification[]=[] - constructor() { } + constructor(private translator: TranslateService) { } - show(origin:string, textOrTpl: string | TemplateRef<any>, options: any = {}) { + public show(origin:string, textOrTpl: string | TemplateRef<any>, options: any = {}): void { let notification = new AppNotification(origin, textOrTpl, "", options); this.toasts.push(notification); this.toastHistory.push(notification); @@ -45,7 +46,7 @@ export class ToastService { console.log("Notification " + notification); } - showStandard(origin:string,textOrTpl:string|TemplateRef<any>, options:any={}) { + public showStandard(origin:string,textOrTpl:string|TemplateRef<any>, options:any={}) : void { options.classname='bg-primary' if (!options.delay) { options.delay=8000 @@ -53,7 +54,17 @@ export class ToastService { this.show(origin,textOrTpl,options) } - showError(origin:string,textOrTpl:string|TemplateRef<any>, options:any={}) { + public showStandardByKey(origin:string,translationKey:string, params:any={}, options:any={} ) : void { + let message:string; + if (params) { + message = this.translator.instant(translationKey, params); + } else { + message = this.translator.instant(translationKey); + } + this.showStandard(origin, message, options); + } + + public showError(origin:string,textOrTpl:string|TemplateRef<any>, options:any={}) : void { options.classname='bg-warning' options.type='error' if (!options.delay) { @@ -62,7 +73,17 @@ export class ToastService { this.show(origin,textOrTpl,options) } - showSuccess(origin:string,textOrTpl:string|TemplateRef<any>, options:any={}) { + public showErrorByKey(origin:string,translationKey:string, params:any={}, options:any={} ) : void { + let message:string; + if (params) { + message = this.translator.instant(translationKey, params); + } else { + message = this.translator.instant(translationKey); + } + this.showError(origin, message, options); + } + + public showSuccess(origin:string,textOrTpl:string|TemplateRef<any>, options:any={}) : void { options.classname='bg-info' options.type='success' if (!options.delay) { @@ -71,6 +92,17 @@ export class ToastService { this.show(origin,textOrTpl,options) } + public showSuccessByKey(origin:string,translationKey:string, params:any={}, options:any={} ) : void { + let message:string; + if (params) { + message = this.translator.instant(translationKey, params); + } else { + message = this.translator.instant(translationKey); + } + this.showSuccess(origin, message, options); + } + + remove(toast) { this.toasts = this.toasts.filter(t => t != toast); } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json index 0be67d397..e39cf2157 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json @@ -143,7 +143,17 @@ "noUsersAssigned": "There are no users assigned to this role", "assignUserSearch": "Search and assign users to this role", "userSearchFailed": "Sorry, could not load users", - "assignButton": "Assign" + "assignButton": "Assign", + "errors": { + "updateFailed": "Could not update role {role_id}: {message}", + "assignFailed": "Could not assign role {role_id} to user {user_id}: {message}", + "retrieveFailed": "Could not retrieve role information: {message}" + }, + "success": { + "updated": "Role {role_id} was updated", + "assign": "Role {role_id} was assigned to user {user_id}", + "unassign": "Removed assignment of {role_id} to {user_id}" + } }, "attributes": { "id": "Identifier", |