Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: return the result #521

Open
FoxTes opened this issue Oct 18, 2023 · 1 comment
Open

Question: return the result #521

FoxTes opened this issue Oct 18, 2023 · 1 comment

Comments

@FoxTes
Copy link

FoxTes commented Oct 18, 2023

Hello, colleagues.
I can't figure out how to translate this code, namely, it confuses the function in case of failure.

Is it possible to combine it somehow?

Source code

        if (!FullNameRegex.IsValid(message.Text!))
        {
            return await telegramBotClient.SendTextMessageAsync(
                message.Chat.Id, 
                ErrorMessage.ValidationFullName,
                cancellationToken: ct);
        }

        var fullName = await daDataService.ParseFullName(message.Text!);
        if (fullName is null)
        {
            return await telegramBotClient.SendTextMessageAsync(
                message.Chat.Id, 
                ErrorMessage.ValidationFullName, 
                cancellationToken: ct);
        }

        user.Gender = fullName.gender;
        user.Name = fullName.name;
        user.Surname = fullName.surname;
        user.Patronymic = fullName.patronymic;
        user.ActionType = ActionType.Indefinite;
        await userService.UpdateAsync(user, ct);

        return await SendInputWorkoutType(message, ct);

What happened

        var x = await FullNameRegex.IsValidTest(message.Text!)
            .Bind(() => daDataService.ParseFullNameTest(message.Text!));
        if (x.IsFailure)
        {
            return await telegramBotClient.SendTextMessageAsync(
                message.Chat.Id, 
                ErrorMessage.ValidationFullName,
                cancellationToken: ct);
        }
        
        and further...
@PNZeml
Copy link
Contributor

PNZeml commented Nov 24, 2023

You can nest an error handler inside Bind, Check, whatever. For your case, more optimal is to have a single "Error case handle" at the end of the chain, I think.

using CSharpFunctionalExtensions;

var user = new User();

await Result.Success(new Message("Bar", "Test Person"))
    .Ensure(message => Result.SuccessIf(DoesTextHaveValidFullName(message.Text), message, Errors.FullNameIsInvalid)
        .TapError(e => new TelegramBotClient().ReplyToMessageAsync(message, "Bot1", e))
    )
    .Bind(message => new SomeDataService().ExtractFullName(message.Text)
        // Translate a service level error to client one, I guess
        .MapError(_ => Errors.FullNameIsInvalid)
        .TapError(e => new TelegramBotClient().ReplyToMessageAsync(message, "Bot2", e))
    )
    .Bind(n => user.UpdatePersonalInfo(n))
    .Tap(u => new UserService().UpdateAsync(u))
    .Tap(() => Console.WriteLine("User personal info has been updated"))
    .TapError(e => Console.WriteLine($"[ERROR] Parse error occurred: {e}"));

bool DoesTextHaveValidFullName(string name) {
    return string.IsNullOrEmpty(name) == false;
}

public record Message(string User, string Text);

public class User {
    public Result<User> UpdatePersonalInfo(string fullName) {
        return this;
    }
}

public static class Errors {
    public const string FullNameIsInvalid = "Invalid Full name";
}

public class SomeDataService {
    public Result<string> ExtractFullName(string message) {
        return Result.SuccessIf(message.Contains("Test Person"), "FullName", "Message does not contain full name");
    } 
}

public class TelegramBotClient {
    public Task ReplyToMessageAsync(Message message, string user, string text) {
        Console.WriteLine($"[{user}] [REPLY TO {message.Text}]: {text}");
        return Task.CompletedTask;
    }
}

public class UserService {
    public Task UpdateAsync(User user) {
        return Task.CompletedTask;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants