• English
  • no-try-catch-in-callback

    Disallows try-catch blocks inside callbacks passed to @praha/byethrow functions such as Result.andThen, Result.map, etc.

    Rule details

    A try-catch inside a @praha/byethrow callback is a sign that error handling has escaped the Result model. Use Result.fn() to wrap potentially-throwing code into a Result, keeping the pipeline clean.

    Incorrect

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    // ❌ try-catch inside a callback const
    const result: Result.Result<any, ParseError>
    result
    =
    import Result
    Result
    .
    const pipe: <Result.Result<"{\"key\": \"value\"}", never>, Result.Result<any, ParseError>>(a: Result.Result<"{\"key\": \"value\"}", never>, ab: (a: Result.Result<"{\"key\": \"value\"}", never>) => Result.Result<any, ParseError>) => Result.Result<any, ParseError> (+25 overloads)
    pipe
    (
    import Result
    Result
    .
    const succeed: <"{\"key\": \"value\"}">(value: "{\"key\": \"value\"}") => Result.Result<"{\"key\": \"value\"}", never> (+1 overload)
    succeed
    ('{"key": "value"}'),
    import Result
    Result
    .
    const andThen: <Result.Result<"{\"key\": \"value\"}", never>, Result.Success<any> | Result.Failure<ParseError>>(fn: (a: "{\"key\": \"value\"}") => Result.Success<any> | Result.Failure<ParseError>) => (result: Result.Result<"{\"key\": \"value\"}", never>) => Result.Result<any, ParseError> (+1 overload)
    andThen
    ((
    value: "{\"key\": \"value\"}"
    value
    ) => {
    try { return
    import Result
    Result
    .
    const succeed: <any>(value: any) => Result.Result<any, never> (+1 overload)
    succeed
    (
    var JSON: JSON

    An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.

    JSON
    .
    JSON.parse(text: string, reviver?: (this: any, key: string, value: any) => any): any

    Converts a JavaScript Object Notation (JSON) string into an object.

    @paramtext A valid JSON string.@paramreviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is.@throws{SyntaxError} If text is not valid JSON.
    parse
    (
    value: "{\"key\": \"value\"}"
    value
    ));
    } catch { return
    import Result
    Result
    .
    const fail: <ParseError>(error: ParseError) => Result.Result<never, ParseError> (+1 overload)
    fail
    (new
    constructor ParseError(message?: string, options?: ErrorOptions): ParseError (+1 overload)
    ParseError
    ());
    } }), );

    Correct

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const parser: (value: string) => Result.ResultAsync<any, ParseError>
    parser
    =
    import Result
    Result
    .
    fn<(value: string) => any, ParseError>(options: {
        try: (value: string) => any;
        catch: (error: unknown) => ParseError;
    }): (value: string) => Result.ResultAsync<any, ParseError> (+3 overloads)
    export fn

    Wraps a function that may throw and returns a new function that returns a Result or ResultAsync .

    You can use either a custom catch handler or rely on the safe: true option to assume the function cannot throw.

    @function@typeParamT - The function type to execute (sync or async) or a Promise type.@typeParamE - The error type to return if catch is used.@returnsA new function that returns a Result or ResultAsync wrapping the original function's return value or the caught error.@example

    Sync try-catch

    import { Result } from '@praha/byethrow';
    
    const fn = Result.fn({
    try: (x: number) => {
    if (x < 0) throw new Error('Negative!');
    return x * 2;
    },
    catch: (error) => new Error('Oops!', { cause: error }),
    });
    
    const result = fn(5); // Result.Result<number, Error>
    @example

    Sync safe

    import { Result } from '@praha/byethrow';
    
    const fn = Result.fn({
    safe: true,
    try: (x: number) => x + 1,
    });
    
    const result = fn(1); // Result.Result<number, never>
    @example

    Async try-catch

    import { Result } from '@praha/byethrow';
    
    const fn = Result.fn({
    try: async (id: string) => await fetch(`/api/data/${id}`),
    catch: (error) => new Error('Oops!', { cause: error }),
    });
    
    const result = await fn('abc'); // Result.ResultAsync<Response, Error>
    @example

    Async safe

    import { Result } from '@praha/byethrow';
    
    const fn = Result.fn({
    safe: true,
    try: async () => await Promise.resolve('ok'),
    });
    
    const result = await fn(); // Result.ResultAsync<string, never>
    @categoryCreators
    fn
    ({
    try: (value: string) => any
    try
    : (
    value: string
    value
    : string) =>
    var JSON: JSON

    An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.

    JSON
    .
    JSON.parse(text: string, reviver?: (this: any, key: string, value: any) => any): any

    Converts a JavaScript Object Notation (JSON) string into an object.

    @paramtext A valid JSON string.@paramreviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is.@throws{SyntaxError} If text is not valid JSON.
    parse
    (
    value: string
    value
    ),
    catch: (error: unknown) => ParseError
    catch
    : (
    error: unknown
    error
    : unknown) => new
    constructor ParseError(message?: string, options?: ErrorOptions): ParseError (+1 overload)
    ParseError
    (),
    }); // ✅ wrapping with Result.fn() const
    const result: Result.ResultAsync<any, ParseError>
    result
    =
    import Result
    Result
    .
    const pipe: <Result.Result<"{\"key\": \"value\"}", never>, Result.ResultAsync<any, ParseError>>(a: Result.Result<"{\"key\": \"value\"}", never>, ab: (a: Result.Result<"{\"key\": \"value\"}", never>) => Result.ResultAsync<any, ParseError>) => Result.ResultAsync<any, ParseError> (+25 overloads)
    pipe
    (
    import Result
    Result
    .
    const succeed: <"{\"key\": \"value\"}">(value: "{\"key\": \"value\"}") => Result.Result<"{\"key\": \"value\"}", never> (+1 overload)
    succeed
    ('{"key": "value"}'),
    import Result
    Result
    .
    const andThen: <Result.Result<"{\"key\": \"value\"}", never>, Result.ResultAsync<any, ParseError>>(fn: (a: "{\"key\": \"value\"}") => Result.ResultAsync<any, ParseError>) => (result: Result.Result<"{\"key\": \"value\"}", never>) => Result.ResultAsync<any, ParseError> (+1 overload)
    andThen
    (
    const parser: (value: string) => Result.ResultAsync<any, ParseError>
    parser
    ),
    );