using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
namespace Swan
{
///
/// Provides methods to perform self-checks in library or application code.
///
public static class SelfCheck
{
///
/// Creates and returns an exception telling that an internal self-check has failed.
/// The returned exception will be of type ; its
/// Message property will contain the specified
/// , preceded by an indication of the assembly, source file,
/// and line number of the failed check.
///
/// The exception message.
/// The path of the source file where this method is called.
/// This parameter is automatically added by the compiler amd should never be provided explicitly.
/// The line number in source where this method is called.
/// This parameter is automatically added by the compiler amd should never be provided explicitly.
///
/// A newly-created instance of .
///
public static InternalErrorException Failure(string message, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0)
=> new InternalErrorException(BuildMessage(message, filePath, lineNumber));
private static string BuildMessage(string message, string filePath, int lineNumber)
{
var frames = new StackTrace().GetFrames();
if (frames == null)
return message;
try
{
filePath = Path.GetFileName(filePath);
}
catch (ArgumentException)
{
}
var frame = frames.FirstOrDefault(f => f.GetMethod().ReflectedType != typeof(SelfCheck));
var sb = new StringBuilder()
.Append('[')
.Append(frame?.GetType().Assembly.GetName().Name ?? "");
if (!string.IsNullOrEmpty(filePath))
{
sb.Append(": ").Append(filePath);
if (lineNumber > 0)
sb.Append('(').Append(lineNumber).Append(')');
}
return sb.Append("] ").Append(message).ToString();
}
}
}