вторник, 22 октября 2019 г.

Exception.Message

понадобилось понять, как формируется текстовое представление Exception, что к чему относится.
написал проверочную программку - см. ниже.


резюме: сначала идет последовательно тип и Message по каждому из цепочки исключений, начиная с самого внешнего.

потом - стек вызовов для каждого исключения, начиная с самого внутреннего. при чем, стек заканчивается на той строке, которая обернута в try/catch, поймавший данное исключение, если только оно не было кинуто дальше.
если же было кинуто дальше - факт поимки никак не отражается.

стектрейс отсчитывается от оператора throw, а не от места, где исключение создано

код программы:

  1. using System;
  2. namespace ConsoleApp1
  3. {
  4.    
  5.     class Program
  6.     {
  7.         static void f4()
  8.         {
  9.             throw new Exception("!!!");
  10.         }
  11.        
  12.         static void f3()
  13.         {
  14.             try
  15.             {
  16.                 f4();
  17.             }
  18.             catch(Exception e)
  19.             {
  20.                 throw new Exception("f3catch", e);
  21.             }
  22.         }
  23.         static void f2()
  24.         {
  25.             f3();
  26.         }
  27.         static void f1()
  28.         {
  29.             try
  30.             {
  31.                 f2();
  32.             }
  33.             catch (Exception e)
  34.             {
  35.                 throw new Exception("f1catch", e);
  36.             }
  37.            
  38.         }
  39.         static void f0()
  40.         {
  41.             try
  42.             {
  43.                 f1();
  44.             }
  45.             catch (Exception e)
  46.             {
  47.                 Console.WriteLine("Exception caught: " e.Message);
  48.                 throw;
  49.             }
  50.         }
  51.         static void f_minus1()
  52.         {
  53.             try
  54.             {
  55.                 f0();
  56.             }
  57.             catch (Exception e)
  58.             {
  59.                 ExceptionThrower(new Exception("via thrower", e));
  60.             }
  61.         }
  62.         private static void ExceptionThrower(Exception e)
  63.         {
  64.             throw e;
  65.         }
  66.         public static void Main()
  67.         {
  68.             try
  69.             {
  70.                 f_minus1();
  71.             }catch(Exception e)
  72.             {
  73.                 Console.WriteLine(e);
  74.             }
  75.             Console.WriteLine("DONE");
  76.             Console.ReadKey();
  77.         }
  78.        
  79.     }
  80. }

аутпут:
Exception caught: f1catch
System.Exception: via thrower ---> System.Exception: f1catch ---> System.Exception: f3catch ---> System.Exception: !!!
   в ConsoleApp1.Program.f4() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 11
   в ConsoleApp1.Program.f3() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 18
   --- Конец трассировки внутреннего стека исключений ---
   в ConsoleApp1.Program.f3() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 22
   в ConsoleApp1.Program.f2() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 28
   в ConsoleApp1.Program.f1() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 35
   --- Конец трассировки внутреннего стека исключений ---
   в ConsoleApp1.Program.f1() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 39
   в ConsoleApp1.Program.f0() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 53
   в ConsoleApp1.Program.f_minus1() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 61
   --- Конец трассировки внутреннего стека исключений ---
   в ConsoleApp1.Program.ExceptionThrower(Exception e) в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 71
   в ConsoleApp1.Program.f_minus1() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 65
   в ConsoleApp1.Program.Main() в C:\TestProjects\ConsoleApp1\ConsoleApp1\Program.cs:строка 79
DONE

вторник, 18 июня 2019 г.

IIS - редирект запросов с тестового сервера на девелоперский localhost

На работе возникла ситуация:
JS-баг , воспроизводящийся только на реальном телефоне, но не в эмуляции мобильного устройства в F12 Chrome

у тестовых мобильных устройств нет доступа во внутреннюю сеть, за исключением 80 и 81 портов тестового сервера.
то есть, мне светил такой процесс отладки: изменил что-то в своей Visual Studio, вручную копирую измененный файл на тестовый сервер. и так ради каждого (вонючего) изменения.

Я нашел выход из ситуации: настроил на 81 порту тестового сервера прокси на свой девелоперский комп. и тут опишу вкратце процесс.

шаг первый - открыть свой запущенный в localhost проект с браузера другого ПК 

(в моем случае - тестового сервера)
решение проблемы описано вот тут:

нужно помнить, что доступ на уровне файрвола может блокироваться на обоих концах. мне пришлось создать на одном конце (тестовый сервер) исходящее правило для нужного мне порта (порта, под которым моя Студия запускает), на другом (мой комп) - правило для входящих соединений для этого порта.

по поводу команды:
netsh http add urlacl url=http://*:51603/ user=everyone  (upd.:  на следующий день перестала работать отладка просто по F5 на девелоперском компе. проблема решилась, когда отменил эту команду командой
 netsh http delete urlacl url=http://*:51603/ (или как-то так)
)
upd2:  а вот сейчас опять выполнил "netsh http add urlacl " - и ниче , с локалхоста тоже нормально запускается. в общем, ну не знаю.
upd3: кажется, проблема - в том, что мои изменения в файле <solution>/.vs/config/applicationhost.config затираются, нужно их заново вносить периодически



(естественно, порт заменить на нужный)
могу сказать, что не понял сходу, что она делает, прописывает какое-то разрешение. но мне пришлось заменить "user=everyone" на "user=Все" - (имя пользователя everyone в русской винде)

как проверить, устанавливается ли соединение (не закрыто ли на уровне файрвола или сети):

telnet 90.82.14.55 62518
если соединения нет - будет так:

Connecting To 90.82.14.55...Could not open connection to the host, on port 62518
: Connect failed

(на том конце сервер должен быть, естественно, поднят)

в итоге в браузере на тестовом сервере я увидел сайт, запущенный в вижуал-студии на моем компе


шаг второй: настройка проксирования в IIS

основывался на этой статье:

скачал по приведенной в статье ссылке оффлайн-установщик модуля 
создал единственное правило типа "обратный прокси-сервер"

в первую строчку ввел 
90.82.14.55:62518
остальное все оставил без изменений.


подводные камни:
1) по окончании создания убедитесь, что правило создано и отображается в IIS (у меня с первого раза просто не сохранилось, почему-то)
2) имейте в виду, что проксируются только те запросы, которые не обрабатывает, например, подключенное к подпапке приложение. мне тестовый экземпляр приложения пришлось удалить


после этого заработало!

единственно, rewriter-правило теперь применяется ко всем запросам. чтоб оно применялось только  к запросам на определенный порт - добавляем в правило условие:
{SERVER_PORT} - matches the pattern - номер порта



мой комп: Windows 10, Visual Studio 2017
на тестовом сервере: IIS  8.5, Windows Server 2012

P.S. помните, что на реальном телефоне JS и CSS кешируются (для того, чтоб побороть проблему, планирую подключить телефон к DevTools (F12) на ПК и поставить галочку "disable cache", но это уже другая ичтория)

пятница, 8 февраля 2019 г.

SSD на комп

я только что на свой старенький тормозящий комп поставил SSD-диск.

ребята, у меня слов нет! оказывается, у меня великолепный вычислительный ястреб, который выполняет команды прежде, чем я успеваю их додумать!!

нет, реально, разница более, чем разительна!
я так отвык, что жмешь на "панель управления", и она открывается сразу, а не через 5 секунд :(((

при чем, диск - с Алиэкспресса, цена вопроса - 15 тыщ!
как же я доволен!

подробности: Lenovo Y510P, windows 8.1
диск: https://ru.aliexpress.com/item/Zheino-SATA-III-60-GB-120-GB-240-GB-360/32842131727.html
адаптер для CD-привода: https://ru.aliexpress.com/item/High-Quality-Universal-2-5-2nd-9-5mm-Ssd-Hd-SATA-Hard-Disk-Drive-HDD-Caddy/32618448549.html

(там кое где родные шурупчики не подошли, поэтому пришлось немного клея применить :))

как перекидывал образ:

за основу взял эту статью:
http://www.outsidethebox.ms/15044/
но почти все сделал по-другому :)

создал загрузочную флешку Windows PE как там сказано (но там упоминается создание переменной среды прямо в консоли - у меня не получилось, пришлось установить глобально)
кстати, чтоб на моем ноуте загрузиться с флешки, пришлось зайти в биос, включить там Legacy support в настройках загрузки. после этого при загрузке компа стало доступно меню загрузки по F12, в котором присутствует и флешка

потом образ системного диска снял не с помощью imagex (которая у меня заглючила), а с помощью dism (https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/capture-and-apply-windows-using-a-single-wim). образ записал на внешний HDD

потом удалил HDD из компа, поставил на его место SSD. и установил на него Windows 7 32 бита (подойдет любая винда, у меня просто эта была под рукой)

потом в windows PE определил, какой раздел (какая буква диска) является диском с виндой и с помощью dism накатил туда сохраненный образ:

после этого выполнил команду
bcdboot W:\Windows
(W: - буква диска с накаченным образом)

все, после этого с нового диска загрузился! (и глазам не поверил , когда скорость загрузки увидел!)

потом вставил старый HDD-диск в слот для DVD-ROM, и комп стал загружаться со старого диска (кошмар вернулся :)). но я выставил нужный порядок загрузки в BIOS, и все стало хорошо.

Кстати, BIOS-то уже не биос, оказывается, а UEFI! Все не так то просто в этом мире! :)

Еще кстати после всех этих манипуляций, кажется, у меня на компе накрылась возможность рекавери. но и фиг с ним :)

да, поскольку SSD-диск - ноунеймовый с алиэкспресса - значимые данные, естественно, будем хранить на HDD

четверг, 31 января 2019 г.

Visual Studio 2017 - забавный глюк

наткнулся на такой баг/особенность Visual Studio 2017:
в Pre-build event command line ввел текст вида:

"$(ProjectDir)build\TsJsRemover\TsJsRemover.exe" "$(ProjectDir)"
т.е., должна запускаться утилита TsJsRemover, в которую параметром должен приходить путь к папке проекта.

так вот, путь приходил с ведущей кавычкой. например:
c:\project"
выяснилось, что это - известный баг, и обходное решение - в параметре перед закрывающей кавычкой поставить пробел:
"$(ProjectDir)build\TsJsRemover\TsJsRemover.exe" "$(ProjectDir) "
(ссылку на решение, к сожалению, потерял )

P.S. утилита "TsJsRemover" была написана чтобы нейтрализовать последствия другого достаточно опасного каприза Студии, касающегося TypeScript. 

среда, 23 января 2019 г.

MEmu - эмулятор Android

понадобилось мне испытать некоторые приложения, прежде чем их на устройство устанавливать (устройство китайское, если его запороть - не известно, как сложно будет восстановить).
задался целью испытать на эмуляторе.
Путем проб и ошибок (довольно нудным и долгим) обнаружил хороший эмулятор:

MEmu

прям, андроид на ПК, кайф, рекомендую!

столкнулся с проблемой - изображение лагало (перевернутое, мерцает) - в настройках видео конкретной виртуальной машины изменил OpenGL на DirectX - все заработало

у меня Windows 8.1 64, Core i7, 8Gb оперативы

а, и еще, в процессе установки другого жмулятора я в биосе включил Hardware Virtualization

https://ru.bignox.com/nox-app-player/archives/149

https://forums.lenovo.com/t5/Lenovo-P-Y-and-Z-series/How-to-Enable-Hardware-virtualization-on-IdeaPad-Y510p/ta-p/1394215

не знаю, повлияло ли это на работоспособность MEmu

вторник, 8 января 2019 г.

Ситуация с кодировкой в проектах Visual Studio

UTF8 - кодировка, в которой (грубо говоря) латинские буквы и символы кодируются одним байтом, а символы других алфавитов - несколькими (русского и казахского - двумя)
BOM - Byte Ordering Mark - грубо говоря, 3 байта в начале текстового файла, которые сообщают о том, что текст - в кодировке UTF-8
  
в идеале было бы хорошо иметь такую ситуацию: все файлы трактуются как UTF-8 без BOM.
Потому что от BOM бывают проблемы. в частности, при формировании HTML через файлы razor в итоговом HTML в середине (не в начале) файла может быть BOM. причина - мы инклудим (например, RenderPartial) cshtml-файл, а этот файл начинается с BOM-метки.

но такой настройки я в Студии не нашел. так что, остается прийти к соглашению о том, что все файлы проекта у нас будут в формате UTF-8 с BOM. кстати, обработчик TypeScript тупит иногда, если у TS-файла нет BOM.

если файл создается в Студии - он будет создан как UTF-8 с BOM.
проблема может быть при добавлении существующего файла к проекту:
если существующий файл без BOM и без кириллицы добавить в проект  - он трактуется как ANSI, и если в дальнейшем будет добавлена кириллица - она будет сохранена в кодировке 1251. И у нас появляются проблемы. например, если речь идет о JS/TS-файле - т.к. сайты у нас на UTF-8 - при работе со строкой в кодировке 1251 пользователь увидит квадратики или каракули.
Вывод: разработчик должен следить, чтобы добавляемые в проект файлы были в кодировке UTF-8 с BOM.
посмотреть кодировку можно, например, в Notepad++
 
P.S. экспериментальным путем я установил, что при формировании бандлов BOM если и вставляется, то только в самое начало (как положено)

понедельник, 7 января 2019 г.

как убедиться, что не коммитится ничего лишнего при массовой замене строки в файлах проекта

как программист осторожный, я следую правилу: прежде, чем что-то закоммитить, я просматриваю все сделанные изменения. обычно я делаю это средствами Tortoice Git. но однажды столкнулся с ситуацией, когда это оказалось невозможно. Вот моя история:

я столкнулся с ситуацией:  изменил пространство имен для повсеместно используемого класса
в результате , помимо пары прочих изменений, в около 150 файлах строка  "namespace kaspihelp.Interfaces.DependencyInjection" была заменена на "using kaspi.CommonUtilities.DependencyInjection;"
вручную просмотреть изменения в каждом файле перед коммитом с помощью tortoice git - нереально, да и недостойное программиста занятие.
нашел такой выход:
1)  выполняем в консоли команду
git diff --text --minimal >c:\tmp\_gitoutput.txt

в аутпуте-файле - информация обо всех изменениях. собственно, строки с изменениями начинаются с единичных символов "+" или "-"

грохаем такие строки, много раз повторяющиеся (реплейсим чем-нибудь)
смотрим через поиск по регуляркам в notepad++ "^\-[^-]" и "^\+[^+]" оставшиеся изменения - таким образом проходимся по всем прочим изменениям

UPD: написал код, формирующий список файлов, заслуживающих внимания. не судите строго. мож кому пригодится