<commit_before>﻿using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Common.Errors;
using Common.Extensions;
using SQLDatabase.Commands;

namespace SQLDatabase.Errors
{
    /// <summary>
    /// Records exceptions into the database
    /// </summary>
    internal class ErrorHandler : IErrorHandler
    {
        // ReSharper disable once InconsistentNaming
        private const string ErrorReportingURL = "https://github.com/matthew-a-thomas/gps-logger/issues/new";

        private readonly Func<ITransaction> _transactionFactory;

        public ErrorHandler(Func<ITransaction> transactionFactory)
        {
            _transactionFactory = transactionFactory;
        }

        private static (string hash, string message) ComputeHashCodeFor(Exception e)
        {
            if (e == null)
                return (hash: "", message: "");
            var message = e.ToString();
            using (var hasher = SHA256.Create())
            {
                var hash = hasher.ComputeHash(Encoding.UTF8.GetBytes(message)).ToHexString();
                return (hash: hash, message: message);
            }
        }

        private async Task<string> HandleInternal(Exception e)
        {
            (var eHashCode, var eMessage) = ComputeHashCodeFor(e);
            try
            {
                var id = Guid.NewGuid().ToString();
                using (var transaction = _transactionFactory())
                {
                    await transaction.ExecuteAsync(Command.Create(
                        @"
insert into
    exceptions (
        id,
        message,
        hash
    )
values (
    @id,
    @message,
    @hash
)
",
                        new KeyValuePair<string, object>("@id", id),
                        new KeyValuePair<string, object>("@message", eMessage),
                        new KeyValuePair<string, object>("@hash", eHashCode)
                        ));
                    transaction.Commit();
                }
                return $"An error happened internally. Please report this as an issue here, making sure to include the ID \"{id}\" in your description: {ErrorReportingURL}";
            }
            catch (Exception e2)
            {
                (var e2HashCode, var _) = ComputeHashCodeFor(e2);
                return $"Ironically, there was an exception in some exception-handling code. The hash code of the exception is {e2HashCode}, and the hash code of the exception that was supposed to be handled is {eHashCode}. Please report this as an issue here, making sure to include these two hash codes in your description: {ErrorReportingURL}";
            }
        }

        public object Handle(Exception e) => HandleInternal(e);
    }
}<commit_msg>Forgot to wait for async to complete<commit_after>﻿using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Common.Errors;
using Common.Extensions;
using SQLDatabase.Commands;

namespace SQLDatabase.Errors
{
    /// <summary>
    /// Records exceptions into the database
    /// </summary>
    internal class ErrorHandler : IErrorHandler
    {
        // ReSharper disable once InconsistentNaming
        private const string ErrorReportingURL = "https://github.com/matthew-a-thomas/gps-logger/issues/new";

        private readonly Func<ITransaction> _transactionFactory;

        public ErrorHandler(Func<ITransaction> transactionFactory)
        {
            _transactionFactory = transactionFactory;
        }

        private static (string hash, string message) ComputeHashCodeFor(Exception e)
        {
            if (e == null)
                return (hash: "", message: "");
            var message = e.ToString();
            using (var hasher = SHA256.Create())
            {
                var hash = hasher.ComputeHash(Encoding.UTF8.GetBytes(message)).ToHexString();
                return (hash: hash, message: message);
            }
        }

        private async Task<string> HandleInternalAsync(Exception e)
        {
            (var eHashCode, var eMessage) = ComputeHashCodeFor(e);
            try
            {
                var id = Guid.NewGuid().ToString();
                using (var transaction = _transactionFactory())
                {
                    await transaction.ExecuteAsync(Command.Create(
                        @"
insert into
    exceptions (
        id,
        message,
        hash
    )
values (
    @id,
    @message,
    @hash
)
",
                        new KeyValuePair<string, object>("@id", id),
                        new KeyValuePair<string, object>("@message", eMessage),
                        new KeyValuePair<string, object>("@hash", eHashCode)
                        ));
                    transaction.Commit();
                }
                return $"An error happened internally. Please report this as an issue here, making sure to include the ID \"{id}\" in your description: {ErrorReportingURL}";
            }
            catch (Exception e2)
            {
                (var e2HashCode, var _) = ComputeHashCodeFor(e2);
                return $"Ironically, there was an exception in some exception-handling code. The hash code of the exception is {e2HashCode}, and the hash code of the exception that was supposed to be handled is {eHashCode}. Please report this as an issue here, making sure to include these two hash codes in your description: {ErrorReportingURL}";
            }
        }

        public object Handle(Exception e) => HandleInternalAsync(e).WaitAndGet();
    }
}
{'fraction_non_alphanumeric': 0.09147204529370134, 'fraction_numerical': 0.0028308563340410475, 'mean_word_length': 1.9535005224660398, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4534011', 'n_tokens_mistral': 1433, 'n_tokens_neox': 1378, 'n_words': 418}