Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ошибка Внешнее исключение (System.ArgumentException): Item has already been added. Key in dictionary: ‘HOME’ Key being added: ‘home’} #33

Closed
artbear opened this issue Apr 20, 2018 · 25 comments · Fixed by EvilBeaver/OneScript#743
Assignees
Milestone

Comments

@artbear
Copy link
Owner

artbear commented Apr 20, 2018

Приезжает ошибка от разных пользователей

Например,

С какого-то времени, точно уже не помню, 
коммит через SourceTree выдает ошибку, если в репо установлен precommit1c:
ИНФОРМАЦИЯ - Проверка необходимости выгрузки файла 
c:\testgit\MIS_TEMPLATES.epf в каталог c:\testgit\src, корень c:\testgit
ОШИБКА - {Модуль C:\OneScript\lib\1commands\src\Команда.os / 
Ошибка в строке: 310 / Внешнее исключение (System.ArgumentException): 
Item has already been added. Key in dictionary: ‘HOME’ Key being added: ‘home’}

Появилась в последнем релизе
виноват вызов ПеременныеСреды() при создании процесса.

Если КодировкаВывода = Неопределено Тогда
	Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, 
		ПерехватыватьПотоки, ПерехватыватьПотоки, , ПеременныеСреды());
Иначе
	Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, 
		ПерехватыватьПотоки, ПерехватыватьПотоки, КодировкаВывода, ПеременныеСреды());		
КонецЕсли;    

Единственный способ обхода - вернуться к предыдущему релизу :(

/cc @dmpas @EvilBeaver исправьте в движке, реально отравляет жизнь.

@artbear
Copy link
Owner Author

artbear commented Apr 20, 2018

Выложил релиз 1.3.3, в которой включена подробная диагностика вызовов C# - по совету @EvilBeaver

Попытка
		
	Если КодировкаВывода = Неопределено Тогда
		Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, 
ПерехватыватьПотоки, ПерехватыватьПотоки, , ПеременныеСреды());
	Иначе
		Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, 
ПерехватыватьПотоки, ПерехватыватьПотоки, КодировкаВывода, ПеременныеСреды());		
	КонецЕсли;

Исключение
	Инфо = ИнформацияОбОшибке();
	ВызватьИсключение Инфо.ПодробноеОписаниеОшибки();
КонецПопытки;

посмотрим, чего народ сообщит.

@dmpas
Copy link

dmpas commented Apr 20, 2018

@artbear а чего там в движке? кинь ссылку на досаду

@artbear
Copy link
Owner Author

artbear commented Apr 20, 2018

Посидели с коллегой, у которого возникала проблема.
Поставили новый релиз и получили ошибки

git -c diff.mnemonicprefix=false -c core.quotepath=false commit -q -F C:\Users\Дубовкин\AppData\Local\Temp\33eeysib.x1j
Start hooks before commit for v8unpack erf and epf
ИНФОРМАЦИЯ - precommit1c v2.1.1
ИНФОРМАЦИЯ - Проверка необходимости выгрузки файла C:\projects\onec\features\step_definitions\Получение цен с сайта.epf в каталог C:\projects\onec\src, корень C:\projects\onec
ОШИБКА - {Модуль C:\Program Files (x86)\OneScript\lib\1commands\src\Команда.os / Ошибка в строке: 317 / ScriptEngine.Machine.ExternalSystemException: {Модуль C:\Program Files (x86)\OneScript\lib\1commands\src\Команда.os / Ошибка в строке: 312 / Внешнее исключение

(System.ArgumentException): Элемент уже добавлен. Ключ в словаре: "HOME"  Добавляемый ключ: 'home'}    
                        Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, 
ПерехватыватьПотоки, ПерехватыватьПотоки, КодировкаВывода, ПеременныеСреды());           --->

System.ArgumentException: Элемент уже добавлен. Ключ в словаре: "HOME"  Добавляемый ключ: 'home'

   в System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
   в System.Collections.Hashtable.Add(Object key, Object value)
   в System.Collections.Specialized.StringDictionaryWithComparer.Add(String key, String value)
   в System.Diagnostics.ProcessStartInfo.get_EnvironmentVariables()
   в ScriptEngine.HostedScript.Library.ProcessContext.Create(String cmdLine, String currentDir, Boolean redirectOutput, Boolean redirectInput, IValue encoding, MapImpl env)
   в ScriptEngine.HostedScript.Library.SystemGlobalContext.CreateProcess(String cmdLine, String currentDir, Boolean redirectOutput, Boolean redirectInput, IValue encoding, MapImpl env)
   в ScriptEngine.Machine.Contexts.ContextMethodsMapper`1.<>c__DisplayClass25_0`7.<CreateFunction>b__0(TInstance inst, IValue[] args)
   в ScriptEngine.HostedScript.Library.SystemGlobalContext.CallAsFunction(Int32 methodNumber, IValue[] arguments, IValue& retValue)
   в ScriptEngine.Machine.MachineInstance.CallContext(IRuntimeContextInstance instance, Int32 index, MethodInfo& methInfo, IValue[] argValues, Boolean asFunc)
   в ScriptEngine.Machine.MachineInstance.MethodCallImpl(Int32 arg, Boolean asFunc)
   в ScriptEngine.Machine.MachineInstance.CallFunc(Int32 arg)
   в ScriptEngine.Machine.MachineInstance.MainCommandLoop()
   --- Конец трассировки внутреннего стека исключений ---
   в ScriptEngine.Machine.MachineInstance.MainCommandLoop()
   в ScriptEngine.Machine.MachineInstance.ExecuteCode()}

@artbear
Copy link
Owner Author

artbear commented Apr 20, 2018

@artbear
Copy link
Owner Author

artbear commented Apr 20, 2018

if (env != null)
            {
                foreach (var kv in env)
                {
                    sInfo.EnvironmentVariables[kv.Key.AsString()] = kv.Value.AsString();
                }
            }

@artbear
Copy link
Owner Author

artbear commented Apr 20, 2018

Все, у меня идеи закончились.
@dmpas @EvilBeaver ?

@artbear
Copy link
Owner Author

artbear commented Apr 20, 2018

https://msdn.microsoft.com/ru-ru/library/system.collections.specialized.stringdictionary.add(v=vs.90).aspx

Исключение Условие
ArgumentException Запись с таким же ключом уже существует в StringDictionary.

@dmpas
Copy link

dmpas commented Apr 20, 2018

@artbear беда в том, что ПЕРЕД Add оно должно ж было ещё Contains вызвать, который вроде как должен был сказать, что есть уже такой ключ. Беда в платформе. Судя по гуглу, был такой косяк в .net 3.5, но в .net 4.0 как бы починили. И вот опять.

@artbear
Copy link
Owner Author

artbear commented Apr 20, 2018

Сделал исправление - ОДНА СТРОЧКА :)

EvilBeaver/OneScript#743

@artbear
Copy link
Owner Author

artbear commented Apr 25, 2018

Пока не выпустили движок, ошибки продолжают сыпаться.

Придется сделать следующий костыль:

  • вставить попытку-исключение для старта процесса
  • в блоке исключения регуляркой проверить сообщение об ошибке -
    • \(System\.ArgumentException\):[^:]+:.*HOME[^:]+:.*home
  • если строка ошибки совпадает с регуляркой
  • тогда пишем Лог.Предупреждение
  • и вызываем старт процесса без передачи переменных среды

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

еще можно добавить проверку на версию движка -
если версия движка <= 1.0.20, то проверка внутри исключения выполняется иначе не выполняется

@EvilBeaver
Copy link
Collaborator

Т.е. на 19 это работало?

@nixel2007
Copy link
Collaborator

На 19 этого кода в 1коммандс не было.

@EvilBeaver
Copy link
Collaborator

Ну я же пользовался прекоммитом на 20-ке, все работало.

@nixel2007
Copy link
Collaborator

@EvilBeaver у тебя мог быть старый 1коммандс. ииии этот баг проявляется не у всех. у меня, например, работает. суммарно было около десяти репортов за два месяца.

@artbear
Copy link
Owner Author

artbear commented Apr 26, 2018

У меня больше репортов - за последнюю неделю только 5 человек из команд обучения Enterprise обратились, и аналогичные проблемы у их коллег, т.к. машины и ПО одинаковые.

@nixel2007
Copy link
Collaborator

т.к. машины и ПО одинаковые.

как бы все логично, нет? :)

@EvilBeaver
Copy link
Collaborator

Ок, фикс-то выпущен в коммандс? В движок внесен

@nixel2007
Copy link
Collaborator

@EvilBeaver народ уверяет, что фикс движка не помогает.

@artbear
Copy link
Owner Author

artbear commented Apr 26, 2018

Ок, фикс-то выпущен в коммандс? В движок внесен

Пока мной после общения с тобой в 1коммандс внесен фикс, который показывает расширенную инфу (стек движка), и все :)

У меня уже 2-й день не доходят руки закончить доработку #33 (comment)
у меня уже код был в метро написан, на тестирование времени не хватает :(

@artbear
Copy link
Owner Author

artbear commented Apr 26, 2018

Выполнено в #34

@artbear artbear closed this as completed Apr 26, 2018
@artbear artbear self-assigned this Apr 26, 2018
@bpirate999
Copy link

Что обновить чтобы заработало?

@artbear
Copy link
Owner Author

artbear commented Jun 4, 2019

Проблема возникает повторно. Переоткрываю.

@artbear
Copy link
Owner Author

artbear commented Jun 4, 2019

Проблема в том, что при запуске прекоммит1с изнутри команды git
возникают две похожие переменные среды

home = C:\Users\ArturAyukhanov
HOME = C:\Users\ArturAyukhanov

Сейчас в 1коммандс я делаю заглушку (код сейчас запушу)

	ПравильныеПеременныеСреды = УникальныеЗначенияПеременныхСреды();
	Попытка
		
		Если КодировкаВывода = Неопределено Тогда
			Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, , 
				ПравильныеПеременныеСреды);
		Иначе
			Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, 
				КодировкаВывода, ПравильныеПеременныеСреды);
		КонецЕсли;

	Исключение
		...
	КонецПопытки;

Функция УникальныеЗначенияПеременныхСреды()
	ПравильныеПеременныеСреды = Новый Соответствие();
	СуществующиеПеременныеСреды = Новый Соответствие();
	Для Каждого Переменная Из ПеременныеСреды() Цикл
		Ключ = Переменная.Ключ;
		Значение = Переменная.Значение;
		Лог.Отладка("ПеременныеСреды()." + Ключ + " = " + Значение);
		УникальныйКлюч = ВРег(Ключ);
		Если СуществующиеПеременныеСреды.Получить(УникальныйКлюч) = Неопределено Тогда
			СуществующиеПеременныеСреды.Вставить(УникальныйКлюч, Значение);
			ПравильныеПеременныеСреды.Вставить(Ключ, Значение);
			Лог.Отладка("Используем переменную среды - " + Ключ + " = " + Значение);
		Иначе
			Лог.Отладка("Пропущена переменная среды - " + Ключ + " = " + Значение);
		КонецЕсли;
	КонецЦикла;
	Возврат ПравильныеПеременныеСреды;		
КонецФункции

и в логе видно ожидаемое

Отладка - ПеременныеСреды().HOME = C:\Users\ArturAyukhanov
Отладка - Пропущена переменная среды - HOME = C:\Users\ArturAyukhanov

после чего прекоммит1с отрабатывает правильно.

обход на самом деле нужно делать в движке при создании процесса аналогично коду ниже

@EvilBeaver @nixel2007 @dmpas Сможете в движке поправить?

@nixel2007 возможно, в ovm нужно сделать аналогичные правки.

@artbear
Copy link
Owner Author

artbear commented Jun 4, 2019

Нет, все-таки проблема во взаимодействий движка и АПИ запуска процессов в C#

прикладным кодом не обойдешь.

Остается только оставить сделанную мной ранее заглушку :(

	Попытка

		Если КодировкаВывода = Неопределено Тогда
			Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, , ПеременныеСредыПроцесса);
		Иначе
			Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, КодировкаВывода, ПеременныеСредыПроцесса);
		КонецЕсли;

    Исключение
        
        Инфо = ИнформацияОбОшибке();

        // TODO код проверки на регулярку (ниже) убрать после исправления в движке OneScript
        РегуляркаОшибкиПеременныхСреды = Новый РегулярноеВыражение("\(System\.ArgumentException\):[^:]+:.*HOME[^:]+:.*home");
        Если РегуляркаОшибкиПеременныхСреды.Совпадает(Инфо.Описание) Тогда
            Лог.Предупреждение("Возникла ошибка, связанная с переменными среды при старте нового процесса
                |%1
                |
                |Выполняю старт процесса без указания переменных среды.", Инфо.Описание);

            Лог.Отладка("Полное описание ошибки:
                |%1", Инфо.ПодробноеОписаниеОшибки());

            Если КодировкаВывода = Неопределено Тогда
                Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки);
            Иначе
                Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, КодировкаВывода);        
            КонецЕсли;
        Иначе
            ВызватьИсключение Инфо.ПодробноеОписаниеОшибки();
        КонецЕсли;

	КонецПопытки;

@EvilBeaver @nixel2007 @dmpas починить бы движок как я написал выше :(

@artbear
Copy link
Owner Author

artbear commented Jun 4, 2019

Выпущен релиз 1.5.0 с обходом ошибки (из движка?) передачи переменных среды

artbear added a commit to xDrivenDevelopment/precommit1c that referenced this issue Jun 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment