11import { AnyAbility } from './PureAbility' ;
2- import { Normalize } from './types' ;
2+ import { Normalize , Subject } from './types' ;
33import { Generics } from './RuleIndex' ;
44import { getSubjectTypeName } from './utils' ;
55
66export type GetErrorMessage = ( error : ForbiddenError < AnyAbility > ) => string ;
7+ /** @deprecated will be removed in the next major release */
78export const getDefaultErrorMessage : GetErrorMessage = error => `Cannot execute "${ error . action } " on "${ error . subjectType } "` ;
89
910const NativeError = function NError ( this : Error , message : string ) {
@@ -25,7 +26,7 @@ export class ForbiddenError<T extends AnyAbility> extends NativeError {
2526 this . _defaultErrorMessage = typeof messageOrFn === 'string' ? ( ) => messageOrFn : messageOrFn ;
2627 }
2728
28- static from < U extends AnyAbility > ( ability : U ) {
29+ static from < U extends AnyAbility > ( ability : U ) : ForbiddenError < U > {
2930 return new this < U > ( ability ) ;
3031 }
3132
@@ -39,26 +40,33 @@ export class ForbiddenError<T extends AnyAbility> extends NativeError {
3940 }
4041 }
4142
42- setMessage ( message : string ) {
43+ setMessage ( message : string ) : this {
4344 this . message = message ;
4445 return this ;
4546 }
4647
47- throwUnlessCan ( ...args : Parameters < T [ 'can' ] > ) {
48- const rule = this . ability . relevantRuleFor ( ...args ) ;
48+ throwUnlessCan ( ...args : Parameters < T [ 'can' ] > ) : void
49+ throwUnlessCan ( action : string , subject ?: Subject , field ?: string ) : void {
50+ const error = ( this as any ) . unlessCan ( action , subject , field ) ;
51+ if ( error ) throw error ;
52+ }
53+
54+ unlessCan ( ...args : Parameters < T [ 'can' ] > ) : this | undefined
55+ unlessCan ( action : string , subject ?: Subject , field ?: string ) : this | undefined {
56+ const rule = this . ability . relevantRuleFor ( action , subject , field ) ;
4957
5058 if ( rule && ! rule . inverted ) {
5159 return ;
5260 }
5361
54- this . action = args [ 0 ] ;
55- this . subject = args [ 1 ] ;
56- this . subjectType = getSubjectTypeName ( this . ability . detectSubjectType ( args [ 1 ] ) ) ;
57- this . field = args [ 2 ] ;
62+ this . action = action ;
63+ this . subject = subject ;
64+ this . subjectType = getSubjectTypeName ( this . ability . detectSubjectType ( subject ) ) ;
65+ this . field = field ;
5866
5967 const reason = rule ? rule . reason : '' ;
6068 // eslint-disable-next-line no-underscore-dangle
6169 this . message = this . message || reason || ( this . constructor as any ) . _defaultErrorMessage ( this ) ;
62- throw this ; // eslint-disable-line
70+ return this ; // eslint-disable-line consistent-return
6371 }
6472}
0 commit comments