Files
pr-agent/pr_agent/git_providers/utils.py
mrT23 e2b5489495 feat: add error handling for invalid repo settings configuration
- Implement error handling for invalid TOML configurations in repo settings.
- Log warnings and send comments to PRs when configuration errors occur.
- Introduce `handle_configurations_errors` function to manage error reporting.
- Ensure compatibility with different markdown formats for error messages.
2024-10-07 09:13:17 +03:00

103 lines
4.7 KiB
Python

import copy
import os
import tempfile
from dynaconf import Dynaconf
from pr_agent.config_loader import get_settings
from pr_agent.git_providers import get_git_provider, get_git_provider_with_context
from pr_agent.log import get_logger
from starlette_context import context
def apply_repo_settings(pr_url):
git_provider = get_git_provider_with_context(pr_url)
if get_settings().config.use_repo_settings_file:
repo_settings_file = None
try:
try:
repo_settings = context.get("repo_settings", None)
except Exception:
repo_settings = None
pass
if repo_settings is None: # None is different from "", which is a valid value
repo_settings = git_provider.get_repo_settings()
try:
context["repo_settings"] = repo_settings
except Exception:
pass
error_local = None
if repo_settings:
repo_settings_file = None
category = 'local'
try:
fd, repo_settings_file = tempfile.mkstemp(suffix='.toml')
os.write(fd, repo_settings)
new_settings = Dynaconf(settings_files=[repo_settings_file])
for section, contents in new_settings.as_dict().items():
section_dict = copy.deepcopy(get_settings().as_dict().get(section, {}))
for key, value in contents.items():
section_dict[key] = value
get_settings().unset(section)
get_settings().set(section, section_dict, merge=False)
get_logger().info(f"Applying repo settings:\n{new_settings.as_dict()}")
except Exception as e:
get_logger().warning(f"Failed to apply repo {category} settings, error: {str(e)}")
error_local = {'error': str(e), 'settings': repo_settings, 'category': category}
if error_local:
handle_configurations_errors([error_local], git_provider)
except Exception as e:
get_logger().exception("Failed to apply repo settings", e)
finally:
if repo_settings_file:
try:
os.remove(repo_settings_file)
except Exception as e:
get_logger().error(f"Failed to remove temporary settings file {repo_settings_file}", e)
# enable switching models with a short definition
if get_settings().config.model.lower() == 'claude-3-5-sonnet':
set_claude_model()
def handle_configurations_errors(config_errors, git_provider):
try:
if not any(config_errors):
return
for err in config_errors:
if err:
configuration_file_content = err['settings'].decode()
err_message = err['error']
config_type = err['category']
header = f"❌ **PR-Agent failed to apply '{config_type}' repo settings**"
body = f"{header}\n\nThe configuration file needs to be a valid [TOML](https://qodo-merge-docs.qodo.ai/usage-guide/configuration_options/), please fix it.\n\n"
body += f"___\n\n**Error message:**\n`{err_message}`\n\n"
if git_provider.is_supported("gfm_markdown"):
body += f"\n\n<details><summary>Configuration content:</summary>\n\n```toml\n{configuration_file_content}\n```\n\n</details>"
else:
body += f"\n\n**Configuration content:**\n\n```toml\n{configuration_file_content}\n```\n\n"
get_logger().warning(f"Sending a 'configuration error' comment to the PR", artifact={'body': body})
# git_provider.publish_comment(body)
if hasattr(git_provider, 'publish_persistent_comment'):
git_provider.publish_persistent_comment(body,
initial_header=header,
update_header=False,
final_update_message=False)
else:
git_provider.publish_comment(body)
except Exception as e:
get_logger().exception(f"Failed to handle configurations errors", e)
def set_claude_model():
"""
set the claude-sonnet-3.5 model easily (even by users), just by stating: --config.model='claude-3-5-sonnet'
"""
model_claude = "bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0"
get_settings().set('config.model', model_claude)
get_settings().set('config.model_turbo', model_claude)
get_settings().set('config.fallback_models', [model_claude])