Skip to content

Commit 4b3a556

Browse files
committed
Fix ch handling of dynamic import exceptions
1 parent 5fc5887 commit 4b3a556

File tree

5 files changed

+57
-21
lines changed

5 files changed

+57
-21
lines changed

bin/ch/Helpers.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ uint ConcatPath(LPCSTR filenameLeft, uint posPathSep, LPCSTR filenameRight, char
155155
return totalLength;
156156
}
157157

158-
HRESULT Helpers::LoadScriptFromFile(LPCSTR filenameToLoad, LPCSTR& contents, UINT* lengthBytesOut /*= nullptr*/, std::string* fullPath /*= nullptr*/)
158+
HRESULT Helpers::LoadScriptFromFile(LPCSTR filenameToLoad, LPCSTR& contents, UINT* lengthBytesOut /*= nullptr*/, std::string* fullPath /*= nullptr*/, bool shouldMute /*=false */)
159159
{
160160
static char sHostApplicationPathBuffer[MAX_URI_LENGTH];
161161
static uint sHostApplicationPathBufferLength = (uint) -1;
@@ -216,7 +216,7 @@ HRESULT Helpers::LoadScriptFromFile(LPCSTR filenameToLoad, LPCSTR& contents, UIN
216216
// etc.
217217
if (fopen_s(&file, filename, "rb") != 0)
218218
{
219-
if (!HostConfigFlags::flags.MuteHostErrorMsgIsEnabled)
219+
if (!HostConfigFlags::flags.MuteHostErrorMsgIsEnabled && !shouldMute)
220220
{
221221
#ifdef _WIN32
222222
DWORD lastError = GetLastError();

bin/ch/Helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class Helpers
88
{
99
public :
10-
static HRESULT LoadScriptFromFile(LPCSTR filename, LPCSTR& contents, UINT* lengthBytesOut = nullptr, std::string* fullPath = nullptr);
10+
static HRESULT LoadScriptFromFile(LPCSTR filename, LPCSTR& contents, UINT* lengthBytesOut = nullptr, std::string* fullPath = nullptr, bool shouldMute = false);
1111
static LPCWSTR JsErrorCodeToString(JsErrorCode jsErrorCode);
1212
static void LogError(__in __nullterminated const char16 *msg, ...);
1313
static HRESULT LoadBinaryFile(LPCSTR filename, LPCSTR& contents, UINT& lengthBytes, bool printFileOpenError = true);

bin/ch/WScriptJsrt.cpp

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
MessageQueue* WScriptJsrt::messageQueue = nullptr;
4848
std::map<std::string, JsModuleRecord> WScriptJsrt::moduleRecordMap;
4949
std::map<JsModuleRecord, std::string> WScriptJsrt::moduleDirMap;
50+
std::map<JsModuleRecord, ModuleState> WScriptJsrt::moduleErrMap;
5051
std::map<DWORD_PTR, std::string> WScriptJsrt::scriptDirMap;
5152
DWORD_PTR WScriptJsrt::sourceContext = 0;
5253

@@ -481,6 +482,7 @@ JsErrorCode WScriptJsrt::LoadModuleFromString(LPCSTR fileName, LPCSTR fileConten
481482
}
482483

483484
moduleRecordMap[std::string(moduleRecordKey)] = requestModule;
485+
moduleErrMap[requestModule] = RootModule;
484486
}
485487
}
486488
else
@@ -503,9 +505,10 @@ JsErrorCode WScriptJsrt::LoadModuleFromString(LPCSTR fileName, LPCSTR fileConten
503505

504506
errorCode = ChakraRTInterface::JsParseModuleSource(requestModule, dwSourceCookie, (LPBYTE)fileContent,
505507
fileContentLength, JsParseModuleSourceFlags_DataIsUTF8, &errorObject);
506-
if ((errorCode != JsNoError) && errorObject != JS_INVALID_REFERENCE && fileContent != nullptr && !HostConfigFlags::flags.IgnoreScriptErrorCode)
508+
if ((errorCode != JsNoError) && errorObject != JS_INVALID_REFERENCE && fileContent != nullptr && !HostConfigFlags::flags.IgnoreScriptErrorCode && moduleErrMap[requestModule] == RootModule)
507509
{
508510
ChakraRTInterface::JsSetException(errorObject);
511+
moduleErrMap[requestModule] = ErroredModule;
509512
return errorCode;
510513
}
511514
return JsNoError;
@@ -1144,6 +1147,7 @@ bool WScriptJsrt::Uninitialize()
11441147
// to avoid worrying about global destructor order.
11451148
moduleRecordMap.clear();
11461149
moduleDirMap.clear();
1150+
moduleErrMap.clear();
11471151
scriptDirMap.clear();
11481152

11491153
auto& threadData = GetRuntimeThreadLocalData().threadData;
@@ -1867,15 +1871,32 @@ WScriptJsrt::ModuleMessage::~ModuleMessage()
18671871

18681872
HRESULT WScriptJsrt::ModuleMessage::Call(LPCSTR fileName)
18691873
{
1870-
JsErrorCode errorCode;
1874+
JsErrorCode errorCode = JsNoError;
18711875
JsValueRef result = JS_INVALID_REFERENCE;
18721876
HRESULT hr;
18731877
if (specifier == nullptr)
18741878
{
1875-
errorCode = ChakraRTInterface::JsModuleEvaluation(moduleRecord, &result);
1876-
if (errorCode != JsNoError)
1879+
if (moduleErrMap[moduleRecord] != ErroredModule)
18771880
{
1878-
PrintException(fileName, errorCode);
1881+
errorCode = ChakraRTInterface::JsModuleEvaluation(moduleRecord, &result);
1882+
if (errorCode != JsNoError)
1883+
{
1884+
if (moduleErrMap[moduleRecord] == RootModule)
1885+
{
1886+
PrintException(fileName, errorCode);
1887+
}
1888+
else
1889+
{
1890+
bool hasException = false;
1891+
ChakraRTInterface::JsHasException(&hasException);
1892+
if (hasException)
1893+
{
1894+
JsValueRef exception;
1895+
ChakraRTInterface::JsGetAndClearException(&exception);
1896+
exception; //unusued
1897+
}
1898+
}
1899+
}
18791900
}
18801901
}
18811902
else
@@ -1885,13 +1906,17 @@ HRESULT WScriptJsrt::ModuleMessage::Call(LPCSTR fileName)
18851906
errorCode = specifierStr.GetError();
18861907
if (errorCode == JsNoError)
18871908
{
1888-
hr = Helpers::LoadScriptFromFile(*specifierStr, fileContent, nullptr, fullPath);
1909+
hr = Helpers::LoadScriptFromFile(*specifierStr, fileContent, nullptr, fullPath, true);
18891910

18901911
if (FAILED(hr))
18911912
{
18921913
if (!HostConfigFlags::flags.MuteHostErrorMsgIsEnabled)
18931914
{
1894-
fprintf(stderr, "Couldn't load file '%s'\n", specifierStr.GetString());
1915+
auto actualModuleRecord = moduleRecordMap.find(*fullPath);
1916+
if (actualModuleRecord == moduleRecordMap.end() || moduleErrMap[actualModuleRecord->second] == RootModule)
1917+
{
1918+
fprintf(stderr, "Couldn't load file '%s'\n", specifierStr.GetString());
1919+
}
18951920
}
18961921
LoadScript(nullptr, fullPath == nullptr ? *specifierStr : fullPath->c_str(), nullptr, "module", true, WScriptJsrt::FinalizeFree, false);
18971922
goto Error;
@@ -1937,6 +1962,7 @@ JsErrorCode WScriptJsrt::FetchImportedModuleHelper(JsModuleRecord referencingMod
19371962
InitializeModuleInfo(specifier, moduleRecord);
19381963
std::string pathKey = std::string(fullPath);
19391964
moduleRecordMap[pathKey] = moduleRecord;
1965+
moduleErrMap[moduleRecord] = ImportedModule;
19401966
ModuleMessage* moduleMessage = WScriptJsrt::ModuleMessage::Create(referencingModule, specifier, &pathKey);
19411967
if (moduleMessage == nullptr)
19421968
{
@@ -1999,7 +2025,8 @@ JsErrorCode WScriptJsrt::NotifyModuleReadyCallback(_In_opt_ JsModuleRecord refer
19992025
ChakraRTInterface::JsGetAndClearException(&exception);
20002026
exception; // unused
20012027
}
2002-
else
2028+
2029+
if (exceptionVar != nullptr || moduleErrMap[referencingModule] != ErroredModule)
20032030
{
20042031
WScriptJsrt::ModuleMessage* moduleMessage =
20052032
WScriptJsrt::ModuleMessage::Create(referencingModule, nullptr);

bin/ch/WScriptJsrt.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
#pragma once
66
#include <list>
77

8+
enum ModuleState
9+
{
10+
RootModule,
11+
ImportedModule,
12+
ErroredModule
13+
};
14+
815
class WScriptJsrt
916
{
1017
public:
@@ -141,5 +148,6 @@ class WScriptJsrt
141148
static DWORD_PTR sourceContext;
142149
static std::map<std::string, JsModuleRecord> moduleRecordMap;
143150
static std::map<JsModuleRecord, std::string> moduleDirMap;
151+
static std::map<JsModuleRecord, ModuleState> moduleErrMap;
144152
static std::map<DWORD_PTR, std::string> scriptDirMap;
145153
};

lib/Runtime/Language/SourceTextModuleRecord.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -955,16 +955,6 @@ namespace Js
955955
{
956956
OUTPUT_TRACE_DEBUGONLY(Js::ModulePhase, _u("ModuleEvaluation(%s)\n"), this->GetSpecifierSz());
957957

958-
#if DBG
959-
if (childrenModuleSet != nullptr)
960-
{
961-
childrenModuleSet->EachValue([=](SourceTextModuleRecord* childModuleRecord)
962-
{
963-
AssertMsg(childModuleRecord->WasParsed(), "child module needs to have been parsed");
964-
AssertMsg(childModuleRecord->WasDeclarationInitialized(), "child module needs to have been initialized.");
965-
});
966-
}
967-
#endif
968958
if (!scriptContext->GetConfig()->IsES6ModuleEnabled() || WasEvaluated())
969959
{
970960
return nullptr;
@@ -986,6 +976,17 @@ namespace Js
986976
}
987977
}
988978

979+
#if DBG
980+
if (childrenModuleSet != nullptr)
981+
{
982+
childrenModuleSet->EachValue([=](SourceTextModuleRecord* childModuleRecord)
983+
{
984+
AssertMsg(childModuleRecord->WasParsed(), "child module needs to have been parsed");
985+
AssertMsg(childModuleRecord->WasDeclarationInitialized(), "child module needs to have been initialized.");
986+
});
987+
}
988+
#endif
989+
989990
Assert(this->errorObject == nullptr);
990991
SetWasEvaluated();
991992

0 commit comments

Comments
 (0)