<commit_before>﻿using System;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using System.Text;
using System.Collections.Generic;

namespace Mindscape.Raygun4Net.Messages
{
  public class RaygunErrorMessage
  {
    public RaygunErrorMessage ()
    {
    }

    public RaygunErrorMessage(Exception exception)
    {
      var exceptionType = exception.GetType();

      Message = string.Format("{0}: {1}", exceptionType.Name, exception.Message);
      ClassName = exceptionType.FullName;

      StackTrace = BuildStackTrace(exception);
      Data = exception.Data;

      if (exception.InnerException != null)
      {
        InnerError = new RaygunErrorMessage(exception.InnerException);
      }
    }

    private RaygunErrorStackTraceLineMessage[] BuildStackTrace(Exception exception)
    {
      var lines = new List<RaygunErrorStackTraceLineMessage>();

      string stackTraceStr = exception.StackTrace;
      if (stackTraceStr == null)
      {
        var line = new RaygunErrorStackTraceLineMessage { FileName = "none", LineNumber = 0 };
        lines.Add(line);
        return lines.ToArray();
      }
      try
      {
        string[] stackTraceLines = stackTraceStr.Split(new char[]{'\n'}, StringSplitOptions.RemoveEmptyEntries);
        foreach (string stackTraceLine in stackTraceLines)
        {
          int lineNumber = 0;
          string fileName = null;
          string methodName = null;
          string className = null;
          string stackTraceLn = stackTraceLine;
          // Line number
          int index = stackTraceLine.LastIndexOf(":");
          if (index > 0)
          {
            bool success = int.TryParse(stackTraceLn.Substring(index + 1), out lineNumber);
            if (success)
            {
              stackTraceLn = stackTraceLn.Substring(0, index);
              // File name
              index = stackTraceLn.LastIndexOf("] in ");
              if (index > 0)
              {
                fileName = stackTraceLn.Substring(index + 5);
                stackTraceLn = stackTraceLn.Substring(0, index);
                // Method name
                index = stackTraceLn.LastIndexOf("(");
                if (index > 0)
                {
                  index = stackTraceLn.LastIndexOf(".", index);
                  if (index > 0)
                  {
                    int endIndex = stackTraceLn.IndexOf("[0x");
                    if (endIndex < 0)
                    {
                      endIndex = stackTraceLn.Length;
                    }
                    methodName = stackTraceLn.Substring(index + 1, endIndex - index - 1).Trim();
                    methodName = methodName.Replace(" (", "(");
                    stackTraceLn = stackTraceLn.Substring(0, index);
                  }
                }
                // Class name
                index = stackTraceLn.IndexOf("at ");
                if (index >= 0)
                {
                  className = stackTraceLn.Substring(index + 3);
                }
              }
              else
              {
                fileName = stackTraceLn;
              }
            }
            else
            {
              index = stackTraceLn.IndexOf("at ");
              if (index >= 0)
              {
                index += 3;
              }
              else
              {
                index = 0;
              }
              fileName = stackTraceLn.Substring(index);
            }
          }
          else
          {
            if (!String.IsNullOrWhiteSpace(stackTraceLn) && stackTraceLn.StartsWith("at "))
            {
              stackTraceLn = stackTraceLn.Substring(3);
            }
            fileName = stackTraceLn;
          }<commit_msg>Improved stack trace parsing<commit_after>﻿using System;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using System.Text;
using System.Collections.Generic;

namespace Mindscape.Raygun4Net.Messages
{
  public class RaygunErrorMessage
  {
    public RaygunErrorMessage ()
    {
    }

    public RaygunErrorMessage(Exception exception)
    {
      var exceptionType = exception.GetType();

      Message = string.Format("{0}: {1}", exceptionType.Name, exception.Message);
      ClassName = exceptionType.FullName;

      StackTrace = BuildStackTrace(exception);
      Data = exception.Data;

      if (exception.InnerException != null)
      {
        InnerError = new RaygunErrorMessage(exception.InnerException);
      }
    }

    private RaygunErrorStackTraceLineMessage[] BuildStackTrace(Exception exception)
    {
      var lines = new List<RaygunErrorStackTraceLineMessage>();

      string stackTraceStr = exception.StackTrace;
      if (stackTraceStr == null)
      {
        var line = new RaygunErrorStackTraceLineMessage { FileName = "none", LineNumber = 0 };
        lines.Add(line);
        return lines.ToArray();
      }
      try
      {
        string[] stackTraceLines = stackTraceStr.Split(new char[]{'\n'}, StringSplitOptions.RemoveEmptyEntries);
        foreach (string stackTraceLine in stackTraceLines)
        {
          int lineNumber = 0;
          string fileName = null;
          string methodName = null;
          string className = null;
          string stackTraceLn = stackTraceLine;
          // Line number
          int index = stackTraceLine.LastIndexOf(":");
          if (index > 0)
          {
            bool success = int.TryParse(stackTraceLn.Substring(index + 1), out lineNumber);
            if (success)
            {
              stackTraceLn = stackTraceLn.Substring(0, index);
            }
          }
          // File name
          index = stackTraceLn.LastIndexOf("] in ");
          if (index > 0)
          {
            fileName = stackTraceLn.Substring(index + 5);
            stackTraceLn = stackTraceLn.Substring(0, index);
          }
          // Method name
          index = stackTraceLn.LastIndexOf("(");
          if (index > 0 && !stackTraceLine.StartsWith("at ("))
          {
            index = stackTraceLn.LastIndexOf(".", index);
            if (index > 0)
            {
              int endIndex = stackTraceLn.IndexOf("[0x");
              if (endIndex < 0)
              {
                endIndex = stackTraceLn.Length;
              }
              methodName = stackTraceLn.Substring(index + 1, endIndex - index - 1).Trim();
              methodName = methodName.Replace(" (", "(");
              stackTraceLn = stackTraceLn.Substring(0, index);

              // Memory address
              index = methodName.LastIndexOf("<0x");
              if (index >= 0)
              {
                fileName = methodName.Substring(index);
                methodName = methodName.Substring(0, index).Trim();
              }

              // Class name
              index = stackTraceLn.IndexOf("at ");
              if (index >= 0)
              {
                className = stackTraceLn.Substring(index + 3);
              }
            }
          }

          if (methodName == null)
          {
            if (!String.IsNullOrWhiteSpace(stackTraceLn) && stackTraceLn.StartsWith("at "))
            {
              stackTraceLn = stackTraceLn.Substring(3);
            }
            fileName = stackTraceLn;
          }

{'fraction_non_alphanumeric': 0.09811735605331867, 'fraction_numerical': 0.006596124776693692, 'mean_word_length': 1.576283185840708, 'pattern_counts': {'":': 2, '<': 8, '<?xml version=': 0, '>': 17, 'https://': 0, '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': '1563672', 'n_tokens_mistral': 1931, 'n_tokens_neox': 1859, 'n_words': 386}