export interface Failure { __failure : true ; httpStatus ? : number ; error : Error | unknown ; messages ? : string [ ] ; } export const failFast = ( message ) : Failure => { return { __failure : true , error : { } , messages : [ message ] , } ; } ; export const failure = ( failure ) : Failure => ( { __failure : true , ... failure , } ) ; export const withFailureMessage = ( failure , message ) : Failure => ( { __failure : true , error : failure . error , httpStatus : failure . httpStatus , messages : [ message , ... ( failure . messages || [ ] ) ] , } ) ; export type Attempt < T extends Exclude < unknown , string | Failure > > = Failure | T ; param attempt export const hasFailed = < T > ( attempt ) : attempt is Failure => typeof attempt === 'object' && '__failure' in attempt ; param attempt export const hasSucceeded = < T > ( attempt ) : attempt is T => ! hasFailed ( attempt ) ; export const attempt = < T > ( promise ) : Promise < Attempt < T > > => new Promise ( resolve => { promise . then ( success => resolve ( success ) ) . catch ( error => { resolve ( { __failure : true , error } ) ; } ) ; } ) ;