var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole(o => o.FormatterName = ConsoleFormatterNames.Json);
builder.Logging.SetMinimumLevel(LogLevel.Information);
var app = builder.Build();
app.Logger.LogInformation("Service {Name} v{Version} starting", "MyService", "1.0.0");
app.MapGet("/", (ILogger<Program> logger) =>
{
logger.LogInformation("Hello, {User}!", "World");
return "OK";
});
app.Run();
----------------------------------------------------------------------------------
// Настройка логгера для вывода в консоль
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();
builder.Logging.SetMinimumLevel(LogLevel.Information);
Что делает эта настройка в проекте RAzorPage ?
та конфигурация настраивает систему логирования в ASP.NET Core (в т.ч. в Razor Pages) так:
builder.Logging.ClearProviders();
Убирает все провайдеры логов, которые добавляются по умолчанию (Console, EventSource, EventLog на Windows и т.д.). Начинаете «с нуля».builder.Logging.AddConsole();
Включает вывод логов в консоль (видно в терминале/консоли при запуске приложения, Docker‑логе и т.п.).builder.Logging.AddDebug();
Включает вывод в Debug-поток (видно в окне Output → Debug в Visual Studio/VS Code с отладкой).builder.Logging.SetMinimumLevel(LogLevel.Information);
Устанавливает глобальный минимальный уровень логирования на Information. В логи попадут сообщения уровней Information, Warning, Error, Critical; Trace и Debug — отфильтруются.
Что это означает для Razor Pages на практике:
- Вы будете видеть в консоли и в окне Output стандартные логи пайплайна ASP.NET Core (запросы, обработка, ошибки), ваших страниц/обработчиков, middleware, а также библиотек (например, EF Core), но только начиная с уровня Information.
- Системные провайдеры, которые вы удалили
ClearProviders(), работать не будут (например, EventLog на Windows), если вы их не добавите явно. - Если у вас есть настройки логирования в appsettings.json, этот код их переопределяет в части провайдеров и глобального минимального уровня. Тонкую фильтрацию по категориям можно добавить дополнительно, например:
builder.Logging.AddFilter("Microsoft.AspNetCore", LogLevel.Warning);
builder.Logging.AddFilter("MyApp.Pages", LogLevel.Debug);
Итог: логи идут только в консоль и Debug-вывод, и только от уровня Information и выше.
Как сделать чтобы все Логи высвечивались
Как будет выглядеть эти настройки
Если нужно видеть вообще все логи (включая Trace/Debug) в консоли и в Output (Debug), установите минимальный уровень Trace и не ставьте ограничивающих фильтров.
Вариант 1. Program.cs (минимальный хостинг .NET 6/7/8)
var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddSimpleConsole(options =>
{
options.SingleLine = false;
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
options.IncludeScopes = true;
});
var app = builder.Build();
app.Run();
Вариант 2. Через appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Trace",
"Microsoft": "Trace",
"System": "Trace",
"Microsoft.Hosting.Lifetime": "Trace"
}
}
}
Если используете appsettings.Development.json, продублируйте там те же уровни, чтобы в Dev всё точно было на Trace.
Проверка:
- Убедитесь, что нигде в коде/конфиге нет
AddFilter с уровнем выше Trace. - Если используете сторонний логгер (например, Serilog), минимальный уровень тоже должен быть
Verbose/Trace, а sink-и (Console, Debug) — подключены.
Какой вид примут log-сообщения в случае этой настройки
builder.Logging.AddSimpleConsole(options =>
{
options.SingleLine = false;
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
options.IncludeScopes = true;
});
--
?
При такой настройке SimpleConsole вывод будет многострочным, с вашим форматом времени в начале, коротким именем уровня, категорией и EventId на первой строке. Затем — отдельные строки с скоупами (если есть), потом сам текст сообщения и, при наличии, исключение со стеком.
Пример (IncludeScopes = true, есть два скоупа, есть исключение):
2025-12-21 14:37:12.345 info: MyApp.Services.UserService[42]
=> userId=123 => op=Create
Пользователь создан
System.InvalidOperationException: Что-то пошло не так
at MyApp.Services.UserService.Create(...) in C:\src\UserService.cs:line 57
...
Без скоупов и без исключения:
2025-12-21 14:37:12.345 dbug: MyApp.Controllers.HomeController[0]
Обрабатываем запрос
Структура строк:
- Префикс: "<timestamp> <level>: <category>[<eventid>]"
- Timestamp — ваш формат: "yyyy-MM-dd HH:mm:ss.fff "
- level — краткое имя уровня: trce/dbug/info/warn/fail/crit
- Category — имя логгера (обычно полное имя типа)
- EventId — числовой идентификатор события
- Далее (при IncludeScopes = true): строка со скоупами вида "=> scope1 => scope2"
- Далее: строка(и) с текстом сообщения
- Если было исключение: его сообщение и стек на следующих строках
Цвета для уровней (если включена цветная консоль) применяются к первой строке, но в тексте выше они не отображены.
Я что-то не увидел выведенные логи.
Выведи логи которые будут иметь при такой конфигурации
Ниже — пример того, как будут выглядеть строки в консольном логере при включённом IncludeScopes = true, с цветовой разметкой (цвета тут не отображены), с сообщениями и с исключением. Формат: первая строка — «уровень: Категория[EventId]», затем (из‑за IncludeScopes) строка со скоупами, далее текст сообщения, затем (если есть) исключение и стек.
info: MyApp.Services.OrderService[101]
=> CorrelationId: 7f2a9c8e9c2b4e2a8b1d => User: alice
Заказ 123 создан успешно
debug: MyApp.Data.InventoryRepository[42]
=> CorrelationId: 7f2a9c8e9c2b4e2a8b1d => User: alice
Запрос остатков: SKU=ABC-001, склад=msk-main
warn: MyApp.Services.InventoryService[0]
=> CorrelationId: 7f2a9c8e9c2b4e2a8b1d => User: alice
Низкий остаток товара SKU=ABC-001: 2 шт
error: MyApp.Controllers.OrdersController[500]
=> CorrelationId: 7f2a9c8e9c2b4e2a8b1d => User: alice
Ошибка при подтверждении заказа 123
System.InvalidOperationException: Невозможно подтвердить заказ в статусе Draft
at MyApp.Domain.Order.Confirm() in /src/MyApp/Domain/Order.cs:line 87
at MyApp.Services.OrderService.ConfirmAsync(Int32 orderId) in /src/MyApp/Services/OrderService.cs:line 152
at MyApp.Controllers.OrdersController.Confirm(Int32 id) in /src/MyApp/Controllers/OrdersController.cs:line 74
trace: MyApp.Infrastructure.Http.HttpClientHandler[200]
=> CorrelationId: 7f2a9c8e9c2b4e2a8b1d => User: alice
HTTP GET https://api.example.com/products/ABC-001 -> 200 OK (142 ms)
Если в конфигурации отключить IncludeScopes, в этих записях пропадёт строка со скоупами (та, что начинается с "=> ..."). Если включён Timestamp (UseUtcTimestamp или включён форматтер с временем), перед уровнем появится метка времени, например:
2025-12-21 12:34:56.789 +03:00 info: MyApp.Services.OrderService[101]
=> CorrelationId: 7f2a9c8e9c2b4e2a8b1d => User: alice
Заказ 123 создан успешно
Нужен пример под вашу точную категорию/форматтер (Simple/Json/Systemd) и уровни? Напишите, что именно включено, и я сгенерирую точный вывод.
Почему в такой конфигурации логов я Вижу еxception в Панели Output Debug в Visual Studio,
а в Консоли я не вижу этих exception ?
Повторю установки
// Настройка логгера для вывода в консоль
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();
//builder.Logging.SetMinimumLevel(LogLevel.Information);
builder.Logging.SetMinimumLevel(LogLevel.Trace);
----
Короткий ответ: в окне Output (Debug) вы видите «first‑chance» исключения от отладчика Visual Studio, а в консоли — только то, что вы сами залогировали через ILogger. Если исключение где‑то перехватывается и не логируется, консоль его не покажет.
Почему так происходит
- Output (Debug) в VS показывает уведомления от отладчика о каждом брошенном исключении (first‑chance), даже если оно было поймано и обработано. Это не лог приложения.
- Консольный провайдер ILogger выводит только ваши лог‑сообщения. Если вы не вызываете logger.LogError(ex, "...") (или другой уровень с параметром exception), стек исключения в консоль не попадет.
Что сделать, чтобы видеть исключения в консоли
- Логируйте исключения явно:
try
{
}
catch (Exception ex)
{
logger.LogError(ex, "Ошибка при выполнении операции X");
throw;
}
- Для ASP.NET Core — подключите middleware, который логирует необработанные исключения:
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is Exception ex)
{
var logger = context.RequestServices.GetRequiredService<ILoggerFactory>()
.CreateLogger("GlobalException");
logger.LogError(ex, "Unhandled exception");
}
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
});
});
В Dev-режиме можно также добавить app.UseDeveloperExceptionPage() — он логирует и показывает страницу ошибки (но это для разработки).
- Убедитесь, что уровни логирования не отфильтровывают нужные категории:
- У вас уже
SetMinimumLevel(LogLevel.Trace), это ок. - Если хотите точнее:
builder.Logging.AddFilter("Microsoft", LogLevel.Information);
builder.Logging.AddFilter("System", LogLevel.Information);
Или задайте через appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Trace",
"Microsoft": "Information",
"System": "Information"
}
}
}
- Проверьте, как именно вы логируете:
- Важно передавать сам
Exception отдельным параметром: logger.LogError(ex, "msg"). Если вы делаете logger.LogError($"Ошибка: {ex}"), стек не будет форматирован как исключение, а выведется просто строка. - Для событий платформы (например,
System.Net.Http) включите соответствующие уровни категорий, иначе детали могут не попадать в лог.
Итог
- Видите в Output, но не в консоли — это нормально: Output показывает first‑chance отладчика, а консоль — только то, что вы залогировали.
- Решение: логировать исключения через ILogger с параметром
Exception, и при необходимости настроить фильтры категорий/уровней.
Вот мой код
---
public class Program
{
public static void Main(string[] args)
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
var builder = WebApplication.CreateBuilder(args);
// Настройка логгера для вывода в консоль
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();
//builder.Logging.SetMinimumLevel(LogLevel.Information);
builder.Logging.SetMinimumLevel(LogLevel.Trace);
// ========== КОНФИГУРАЦИЯ СЕРВИСОВ ==========
ConfigureServices(builder.Services);
var app = builder.Build();
// ========== КОНФИГУРАЦИЯ ПРИЛОЖЕНИЯ ==========
ConfigureApp(app);
app.Run();
}
private static void ConfigureServices(IServiceCollection services)
{
Console.WriteLine("📦 Настройка сервисов...");
// Основные компоненты
services.AddSingleton<TickerManager>();
services.AddSingleton<QuoteSyncService>();
// Фабрика для ChartContainer (зависит от TickerManager)
services.AddSingleton<ChartContainer>(sp =>
{
var tickerManager = sp.GetRequiredService<TickerManager>();
var container = new ChartContainer(tickerManager);
Console.WriteLine($"📊 ChartContainer создан с {container.Count} графиками");
return container;
});
// Фоновые сервисы
services.AddHostedService<QuotesGeneratorService>(sp =>
{
var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
var tickerManager = sp.GetRequiredService<TickerManager>();
var quoteSyncService = sp.GetRequiredService<QuoteSyncService>();
return new QuotesGeneratorService(
loggerFactory.CreateLogger<QuotesGeneratorService>(),
tickerManager,
quoteSyncService
);
});
services.AddHostedService<TradingStrategyService>(sp =>
{
var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
var tickerManager = sp.GetRequiredService<TickerManager>();
var quoteSyncService = sp.GetRequiredService<QuoteSyncService>();
return new TradingStrategyService(
loggerFactory.CreateLogger<TradingStrategyService>(),
tickerManager
, quoteSyncService
);
});
// Web компоненты
services.AddRazorPages();
services.AddControllers();
// Health checks (опционально)
services.AddHealthChecks();
Console.WriteLine("✅ Сервисы настроены");
}
private static void ConfigureApp(WebApplication app)
{
Console.WriteLine("🔧 Настройка приложения...");
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
Console.WriteLine("🔍 Режим разработки включен");
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
Console.WriteLine("🔒 Режим продакшн включен");
}
// Middleware pipeline
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
// Endpoints
app.MapRazorPages();
app.MapControllers();
app.MapHealthChecks("/health");
// Стартовые сообщения
app.Lifetime.ApplicationStarted.Register(() =>
{
Console.WriteLine("\n" + new string('=', 50));
Console.WriteLine("🚀 ТОРГОВАЯ ПЛАТФОРМА ЗАПУЩЕНА");
Console.WriteLine(new string('=', 50));
Console.WriteLine("📊 Тикеров: 24 (AAA-XXX)");
Console.WriteLine("📈 Графиков: 24 (по одному на тикер)");
Console.WriteLine("🤖 Стратегий: 72 (3 стратегии на каждый тикер)");
Console.WriteLine("⏱️ Генерация котировок: каждую секунду");
Console.WriteLine("🌐 Графики доступны по адресу: https://localhost:{порт}/Finance");
Console.WriteLine(new string('=', 50) + "\n");
});
app.Lifetime.ApplicationStopping.Register(() =>
{
Console.WriteLine("\n" + new string('=', 50));
Console.WriteLine("🛑 ОСТАНОВКА ПЛАТФОРМЫ");
Console.WriteLine(new string('=', 50));
});
Console.WriteLine("✅ Приложение настроено");
app.Lifetime.ApplicationStarted.Register(() =>
{
Console.WriteLine("\n" + new string('=', 50));
Console.WriteLine("🚀 ТОРГОВАЯ ПЛАТФОРМА ЗАПУЩЕНА");
Console.WriteLine(new string('=', 50));
// Получаем TickerManager и выводим статистику
var tickerManager = app.Services.GetRequiredService<TickerManager>();
tickerManager.PrintTickerStats();
Console.WriteLine("📈 Графиков: 24 (по одному на тикер)");
Console.WriteLine("🤖 Стратегий: 72 (3 стратегии на каждый тикер)");
Console.WriteLine("⏱️ Генерация котировок: каждую секунду");
Console.WriteLine("🌐 Графики доступны по адресу: https://localhost:{порт}/Finance");
Console.WriteLine(new string('=', 50) + "\n");
});
}
}
---
Добавь в мой код и выложи полный код вот с этими включениями:
Для ASP.NET Core — подключите middleware, который логирует необработанные исключения:
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is Exception ex)
{
var logger = context.RequestServices.GetRequiredService<ILoggerFactory>()
.CreateLogger("GlobalException");
logger.LogError(ex, "Unhandled exception");
}
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
});
});
-----
В Dev-режиме можно также добавить app.UseDeveloperExceptionPage() — он логирует и показывает страницу ошибки (но это для разработки).
----
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
public class Program
{
public static void Main(string[] args)
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();
builder.Logging.SetMinimumLevel(LogLevel.Trace);
ConfigureServices(builder.Services);
var app = builder.Build();
ConfigureApp(app);
app.Run();
}
private static void ConfigureServices(IServiceCollection services)
{
Console.WriteLine("📦 Настройка сервисов...");
services.AddSingleton<TickerManager>();
services.AddSingleton<QuoteSyncService>();
services.AddSingleton<ChartContainer>(sp =>
{
var tickerManager = sp.GetRequiredService<TickerManager>();
var container = new ChartContainer(tickerManager);
Console.WriteLine($"📊 ChartContainer создан с {container.Count} графиками");
return container;
});
services.AddHostedService<QuotesGeneratorService>(sp =>
{
var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
var tickerManager = sp.GetRequiredService<TickerManager>();
var quoteSyncService = sp.GetRequiredService<QuoteSyncService>();
return new QuotesGeneratorService(
loggerFactory.CreateLogger<QuotesGeneratorService>(),
tickerManager,
quoteSyncService
);
});
services.AddHostedService<TradingStrategyService>(sp =>
{
var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
var tickerManager = sp.GetRequiredService<TickerManager>();
var quoteSyncService = sp.GetRequiredService<QuoteSyncService>();
return new TradingStrategyService(
loggerFactory.CreateLogger<TradingStrategyService>(),
tickerManager
, quoteSyncService
);
});
services.AddRazorPages();
services.AddControllers();
services.AddHealthChecks();
Console.WriteLine("✅ Сервисы настроены");
}
private static void ConfigureApp(WebApplication app)
{
Console.WriteLine("🔧 Настройка приложения...");
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
Console.WriteLine("🔍 Режим разработки включен");
}
else
{
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is Exception ex)
{
var logger = context.RequestServices.GetRequiredService<ILoggerFactory>()
.CreateLogger("GlobalException");
logger.LogError(ex, "Unhandled exception");
}
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
});
});
app.UseHsts();
Console.WriteLine("🔒 Режим продакшн включен");
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();
app.MapHealthChecks("/health");
app.Lifetime.ApplicationStarted.Register(() =>
{
Console.WriteLine("\n" + new string('=', 50));
Console.WriteLine("🚀 ТОРГОВАЯ ПЛАТФОРМА ЗАПУЩЕНА");
Console.WriteLine(new string('=', 50));
Console.WriteLine("📊 Тикеров: 24 (AAA-XXX)");
Console.WriteLine("📈 Графиков: 24 (по одному на тикер)");
Console.WriteLine("🤖 Стратегий: 72 (3 стратегии на каждый тикер)");
Console.WriteLine("⏱️ Генерация котировок: каждую секунду");
Console.WriteLine("🌐 Графики доступны по адресу: https://localhost:{порт}/Finance");
Console.WriteLine(new string('=', 50) + "\n");
});
app.Lifetime.ApplicationStopping.Register(() =>
{
Console.WriteLine("\n" + new string('=', 50));
Console.WriteLine("🛑 ОСТАНОВКА ПЛАТФОРМЫ");
Console.WriteLine(new string('=', 50));
});
Console.WriteLine("✅ Приложение настроено");
app.Lifetime.ApplicationStarted.Register(() =>
{
Console.WriteLine("\n" + new string('=', 50));
Console.WriteLine("🚀 ТОРГОВАЯ ПЛАТФОРМА ЗАПУЩЕНА");
Console.WriteLine(new string('=', 50));
var tickerManager = app.Services.GetRequiredService<TickerManager>();
tickerManager.PrintTickerStats();
Console.WriteLine("📈 Графиков: 24 (по одному на тикер)");
Console.WriteLine("🤖 Стратегий: 72 (3 стратегии на каждый тикер)");
Console.WriteLine("⏱️ Генерация котировок: каждую секунду");
Console.WriteLine("🌐 Графики доступны по адресу: https://localhost:{порт}/Finance");
Console.WriteLine(new string('=', 50) + "\n");
});
}
}
1. По сравнению с моим кодом вывод в консоль не изменился.
Output Debug
Exception thrown: 'System.ArgumentException' in System.Private.CoreLib.dll
Exception thrown: 'System.ArgumentException' in System.Private.CoreLib.dll
Exception thrown: 'System.ArgumentException' in System.Private.CoreLib.dll
Почему не выводится местонахождение в коде - номер строки и модуль ?
Если нет возможности обнаружить место ошибки, то такая информация бесполезна.
Коротко: сообщения «Exception thrown: 'System.ArgumentException' in System.Private.CoreLib.dll» в окне Output — это лишь уведомления о first‑chance исключениях. Они не содержат номер строки по дизайну. Чтобы увидеть строку/модуль, нужно либо остановиться на месте выброса, либо иметь полноценный стек в сообщении исключения (а для этого нужны PDB-символы и не оптимизированная сборка).
Что сделать, чтобы увидеть место ошибки:
- Прервать выполнение на выбросе исключения
- Visual Studio: Debug > Windows > Exception Settings.
- Откройте Common Language Runtime Exceptions и найдите System.ArgumentException.
- Поставьте галочку в колонке Thrown (или просто включите Break on all exceptions).
- Запустите под отладчиком (F5). При выбросе VS остановится, и в Call Stack будет ваша строка.
- Убедиться, что есть символы (PDB) и не оптимизированная сборка
- Конфигурация Debug.
- В свойствах проекта: Build → Optimize code = выключено.
- Build → Advanced → Debugging information = full/portable.
- Запустите под F5, не из «опубликованной»/single-file сборки.
- В окне Debug > Windows > Modules проверьте, что для вашего модуля «Symbols loaded = Yes». Если нет — укажите путь к .pdb (Tools > Options > Debugging > Symbols).
- Показ внешнего кода/полный стек
- В окне Call Stack включите «Show External Code» (или временно снимите Tools > Options > Debugging > Enable Just My Code), чтобы увидеть кадры вне вашего проекта.
- Лог стека из кода (если исключение перехватывается и не останавливает отладчик)
- Поймайте исключение и выведите его целиком — тогда в Console пойдут строки и номера (при наличии PDB):
try
{
// ...
}
catch (ArgumentException ex)
{
Console.WriteLine(ex); // содержит сообщение, тип и стек с номерами строк
throw; // опционально, чтобы не скрыть проблему
} - Альтернатива: подписаться на AppDomain.CurrentDomain.FirstChanceException и логировать ex.ToString().
Почему сейчас вы видите только «System.Private.CoreLib.dll» и без строк:
- Это first‑chance уведомление в Output, оно не содержит стека/строк.
- Отладчик не останавливается на исключении (нет Break on throw).
- Символы не загружены или сборка оптимизирована/Release — номера строк теряются.
- Исключение может выбрасываться и перехватываться внутри фреймворка; без остановки вы увидите только сообщение.
Итог: включите Break on throw для ArgumentException, убедитесь в PDB и Debug-сборке, и посмотрите Call Stack — там будет модуль и точная строка. Если нужно, дам точные шаги для вашей IDE/версии .NET (VS, VS Code, Rider).
Что сделать, чтобы увидеть место ошибки:
Прервать выполнение на выбросе исключения
Visual Studio: Debug > Windows > Exception Settings.
Откройте Common Language Runtime Exceptions и найдите System.ArgumentException.
Поставьте галочку в колонке Thrown (или просто включите Break on all exceptions).
Запустите под отладчиком (F5). При выбросе VS остановится, и в Call Stack будет ваша строка.
----
Вот сейчас все полезно.
Нашел ошибочную строку.
System.ArgumentException
HResult=0x80070057
Message=Not a legal OleAut date.
Source=System.Private.CoreLib
StackTrace:
at System.DateTime.DoubleDateToTicks(Double value)
at System.DateTime.FromOADate(Double d)
at QuoteEngine.GetCurrentQuote() in F:\Projects\VS\GS.TradeContext\RazorChartDirFin02253\Core\QuoteEngine.cs:line 119
Отлично, вы нашли место. Ошибка “Not a legal OleAut date” означает, что в DateTime.FromOADate передано значение, которое нельзя преобразовать в OLE Automation date.
Что проверить сразу
- Логируйте само значение d, которое попадает в FromOADate.
- Частые причины:
- d = NaN или Infinity.
- d вне диапазона OLE Automation: от -657435.0 до примерно 2958465.9999999 (т.е. от 1899-12-30 до 9999-12-31).
- Перепутали формат времени: передали Unix timestamp (секунды/миллисекунды с 1970-01-01) вместо OADate.
- Ошибки парсинга числа (локаль: запятая/точка).
- Пустые/NULL значения, которые по пути превращаются в 1E+308, -1, или другое «мусорное» число.
Быстрая защита на месте вызова