tawada / grass-grower

0 stars 0 forks source link

Improve the granularity and clarity of exception handling in the `generate_code_from_issue_and_reply` function. #103

Open tawada opened 3 weeks ago

tawada commented 3 weeks ago

Upon reviewing the provided code, one key issue stands out:

Issue: Exception Handling in generate_code_from_issue_and_reply

While the generate_code_from_issue_and_reply function in routers/code_generator.py handles the primary logic for generating code and replying to the issue, its exception handling requires improvement. Currently, the function tries to perform various critical operations such as modification application, commit, push, and reply to the issue within a single try block. If any operation fails, the corresponding exception is logged, but the function might raise a generic ValueError.

Specific Section:

def generate_code_from_issue_and_reply(issue_id: int, repo: str, branch: str = "main", code_lang: str = "python"):
    # Checkout to the branch
    services.github.setup_repository(repo, branch)

    new_branch = f"update-issue-#{issue_id}"
    if new_branch != branch:
        # Checkout to the a new branch
        services.github.checkout_new_branch(repo, new_branch)

    issue = services.github.get_issue_by_id(repo, issue_id)

    modification = logic.generate_modification_from_issue(repo, issue, code_lang)
    is_valid = logic.verify_modification(repo, modification)
    try:
        if not is_valid:
            raise ValueError(f"Invalid modification {modification}")

        msg = logic.generate_commit_message(repo, issue, modification)
        logic.apply_modification(repo, modification)
        success = services.github.commit(repo, msg)
        if not success:
            log(str(modification), level="info")
            raise ValueError(f"Failed to commit {msg}")
        services.github.push_repository(repo, new_branch)
        issue_message = logic.generate_issue_reply_message(repo, issue, modification, msg)
        services.github.reply_issue(repo, issue.id, issue_message)
    except logic_exceptions.CodeNotModifiedError as err:
        log(f"Code has no changes: {err}", level="info")
        raise
    finally:
        if branch != new_branch:
            services.github.checkout_branch(repo, branch)
            services.github.delete_branch(repo, new_branch)

Proposed Solution:

Isolate and improve exception handling for each critical section. This approach would enhance the maintainability of the code and provide clear, specific error messages for each failure point.

Example Improvement:

Refactor the function as follows:

def generate_code_from_issue_and_reply(issue_id: int, repo: str, branch: str = "main", code_lang: str = "python"):
    # Checkout to the branch
    services.github.setup_repository(repo, branch)
    new_branch = f"update-issue-#{issue_id}"

    if new_branch != branch:
        # Checkout to the a new branch
        try:
            services.github.checkout_new_branch(repo, new_branch)
        except Exception as err:
            log(f"Failed to checkout new branch: {err}", level="error")
            raise

    issue = services.github.get_issue_by_id(repo, issue_id)
    modification = logic.generate_modification_from_issue(repo, issue, code_lang)

    if not logic.verify_modification(repo, modification):
        log(f"Invalid modification {modification}", level="error")
        raise ValueError(f"Invalid modification {modification}")

    try:
        msg = logic.generate_commit_message(repo, issue, modification)
        logic.apply_modification(repo, modification)
    except logic_exceptions.CodeNotModifiedError as err:
        log(f"Code has no changes: {err}", level="info")
        raise
    except Exception as err:
        log(f"Failed to apply modification: {err}", level="error")
        raise

    try:
        if not services.github.commit(repo, msg):
            log(f"Failed to commit message {msg}", level="error")
            raise ValueError(f"Failed to commit {msg}")
    except Exception as err:
        log(f"Failed to commit changes: {err}", level="error")
        raise

    try:
        services.github.push_repository(repo, new_branch)
    except Exception as err:
        log(f"Failed to push changes: {err}", level="error")
        raise

    issue_message = logic.generate_issue_reply_message(repo, issue, modification, msg)
    try:
        services.github.reply_issue(repo, issue.id, issue_message)
    except Exception as err:
        log(f"Failed to reply to issue: {err}", level="error")
        raise
    finally:
        if branch != new_branch:
            try:
                services.github.checkout_branch(repo, branch)
                services.github.delete_branch(repo, new_branch)
            except Exception as err:
                log(f"Failed to clean up branches: {err}", level="error")
                raise

Summary:

Improving exception handling in the generate_code_from_issue_and_reply function will make the code more robust, easier to maintain, and provide more accurate logs that will help in diagnosing issues effectively. Each step of the process is critical and should have its own directed error handling strategy.