来自JS的格式错误的呼叫:字段大小不同

时间:2019-03-10 04:43:51

标签: react-native

运行ios模拟器时出现错误。登录后,该应用就会崩溃。

我在分支机构主管上,一切正常。我创建了一个新的分支“ android”并运行了android模拟器,修复了与android相关的一些问题。然后,我想确保在iPhone上一切看起来还不错,所以我跑到了iPhone模拟器上,那是我得到错误的时间。屏幕不会立即崩溃。登录后立即崩溃。 android模拟器运行得很好。我以为我会'git checkout master'分支来查明到底是什么导致了该错误,但是该错误仍然存​​在于master分支上。这对我来说没有多大意义。

这是我的堆栈跟踪:

Malformed calls from JS: field sizes are different.

[[74,24],[19,1],[[64,2000,1552169087432,false]],415]

RCTFatal
-[RCTCxxBridge handleError:]
__34-[RCTCxxBridge _initializeBridge:]_block_invoke
facebook::react::RCTMessageThread::tryFunc(std::__1::function<void ()> const&)
facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1::operator()() const
void std::__1::__invoke_void_return_wrapper::__call<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&&&)
std::__1::__function::__func<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1, std::__1::allocator<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1>, void ()>::operator()()
std::__1::function<void ()>::operator()() const
invocation function for block in facebook::react::RCTMessageThread::runAsync(std::__1::function<void ()>)
CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK
__CFRunLoopDoBlocks
__CFRunLoopRun
CFRunLoopRunSpecific
+[RCTCxxBridge runRunLoop]
NSThread__start
_pthread_body
_pthread_body
thread_start

我不知道如何调试此问题。它无处不在,恢复到以前的提交无济于事。错误详细信息并没有给我太多帮助。请帮忙!

这是我的package.json依赖项:

"@babel/core": "^7.3.3",
"antd-mobile-rn": "^2.2.1",
"axios": "^0.18.0",
"babel-eslint": "^8.2.2",
"bugsnag-react-native": "^2.14.0",
"bugsnag-sourcemaps": "^1.1.0",
"moment": "^2.24.0",
"node": "^10.15.1",
"npm": "^6.7.0",
"prop-types": "^15.6.1",
"react": "^16.7.0",
"react-native": "^0.58.4",
"react-native-alert-async": "^1.0.3",
"react-native-aws3": "0.0.8",
"react-native-cached-image": "^1.4.3",
"react-native-country-picker-modal": "^0.7.1",
"react-native-elements": "^0.19.0",
"react-native-modalbox": "^1.7.1",
"react-native-photo-upload": "^1.3.0",
"react-native-push-notification": "^3.1.2",
"react-native-router-flux": "^4.0.0-beta.28",
"react-native-step-indicator": "0.0.9",
"react-native-swiper": "^1.5.14",
"react-native-vector-icons": "^4.6.0",
"react-navigation": "^2.18.3",
"rn-fetch-blob": "^0.10.15",
"socks": "^2.3.0",
"tinycolor2": "^1.4.1"

让我知道我可以提供什么其他信息。

7 个答案:

答案 0 :(得分:6)

这是一个非常普遍的错误,其背后可能有多种原因,因此我将发布两种解决此问题的方法:

首先消除悬而未决的果实(NaN、无穷大问题):

  • 第 1 步:复制完整的错误消息,将其粘贴到文本编辑器中,甚至可以使用 https://beautifier.io/

    之类的内容对其进行美化
  • 第 2 步:搜索字符串 NaN 或字符串 Infinit

如果幸运的话,您会注意到您可能不小心将 NaN 值作为组件样式或组件 prop 传递。修复该值将解决问题。您将如何确定是哪个组件或样式,您将检查 NaN 值周围的信息。 (即您传递一个 fontName: 'whatever' 相同的样式,这会暴露问题所在)

为什么会抛出那个错误? (TL/DR):

您可能知道,react-native 过去常常使用 react-native 桥将信息传递给本机端。为此,它使用了一种非常奇怪的数组格式,所以让我们看看上面的错误:

[
    [74, 24],
    [19, 1],
    [
        [64, 2000, 1552169087432, false]
    ], 415
]

这是一个批处理的桥接消息,这基本上意味着,一系列消息通过桥接发送(因为 react-native 将它们批处理以节省资源)。

第一个数组包含被调用的模块ID

第二个数组包含被调用的模块方法ID

第三个数组包含给定这些方法的参数

<块引用>

在上面的例子中,模块 74 调用了 方法 19 并被赋予了参数 [64, 2000, 1552169087432, false] >

问题在这里很容易被识别,因为第二次调用 module 24,它调用了 method 1 期待参数但没有任何东西作为参数传递给它。 为了调用正确,第三个数组应该包含另一个子元素(如下所示:

[
    [74, 24],
    [19, 1],
    [
        [64, 2000, 1552169087432, false],
        [] // <-- that was missing
    ], 415
]

因此 field sizes are different 错误。 那是因为 react-native 期望对于每个给定的调用,所有 3 fields should contain information

缺少 params 的原因是因为我们的一个模块不喜欢我们的输入之一(特别是我们传递的参数类型)并决定静默崩溃。 我们的应用没有崩溃,但通过桥发送了错误的信息。

话虽如此,我们现在要做的就是找出问题所在:

如何排除故障(解决方案):

为了找出麻烦制造者是谁,我们将检查通过上述批处理消息中的网桥发送的所有消息方法调用(如我们的崩溃日志中所示)。< /p> <块引用>

对于上面的问题,我们需要知道id为74的模块是哪个模块,id为19的方法的方法名是什么。

然后,我们将对崩溃报告中看到的每个调用序列重复此操作。

<块引用>

即 id 为 24 的模块,id 为 1 的方法

我们现在需要的是一种将这些 id 转换为实际模块名称和方法名称的方法。 我们很幸运,因为 react-native 通过 BatchedBridge 公开了该信息。当模块为 created 时(通常在应用启动时)react-native keeps a reference of the module id's and method id's。我们将利用它来获取我们需要的模块/方法名称。

在您的代码中的任意位置添加以下代码片段:

if (global.__fbBatchedBridge) {
  const origMessageQueue = global.__fbBatchedBridge;
  const modules = origMessageQueue._remoteModuleTable;
  const methods = origMessageQueue._remoteMethodTable;
  global.findModuleByModuleAndMethodIds = (moduleId, methodId) => {
    console.log(`The problematic line code is in: ${modules[moduleId]}.${methods[moduleId][methodId]}`)
  }
}

您现在要做的就是在应用中的任何位置设置断点,然后尝试将模块/方法 ID 对作为 global.findModuleByModuleAndMethodIds 函数的参数,如下所示:

global.findModuleByModuleAndMethodIds(74, 19);
global.findModuleByModuleAndMethodIds(24, 1);

这将打印嫌疑人的名字。从那时起,您将能够更好地找出问题所在。

例如,第一个调用可能会打印如下内容:Timing.createTimer(这是我们 setTimeout 时 react-native 发送的典型消息,可能与您的崩溃无关。

对我来说,其中一个调用输出:RNFBAnalyticsModule.logEvent 这让我调查了我们如何将事件记录到 firebase(就在崩溃时)却发现我们正在传递一个 moment 作为它的道具之一。 Firebase 不喜欢那样并无声地崩溃,导致上述错误。

我希望这可以为某人节省数小时的头痛 - 我花了数小时来发现上述所有内容。

答案 1 :(得分:1)

就我而言,这是拼写错误的内联样式。

“高度”而不是“高度”...

所以基本上 react-native 没能发现这个问题,差点把我逼疯了。

答案 2 :(得分:1)

我认为当您传递错误的数据类型时会发生这种情况,因此您应该检查触发此错误的代码并从那里开始检查(此字段的输入是否正确)

答案 3 :(得分:0)

我认为这是在您将UnboundLocalError Traceback (most recent call last) /opt/conda/lib/python3.7/site-packages/sklearn/datasets/covtype.py in fetch_covtype(data_home, download_if_missing, random_state, shuffle, return_X_y) 126 try: --> 127 X, y 128 except NameError: UnboundLocalError: local variable 'X' referenced before assignment During handling of the above exception, another exception occurred: ValueError Traceback (most recent call last) <ipython-input-9-fb303a92b6ca> in <module> ----> 1 forest =fetch_covtype() /opt/conda/lib/python3.7/site-packages/sklearn/datasets/covtype.py in fetch_covtype(data_home, download_if_missing, random_state, shuffle, return_X_y) 127 X, y 128 except NameError: --> 129 X, y = _refresh_cache([samples_path, targets_path], 9) 130 # TODO: Revert to the following two lines in v0.23 131 # X = joblib.load(samples_path) /opt/conda/lib/python3.7/site-packages/sklearn/datasets/base.py in _refresh_cache(files, compress) 928 msg = "sklearn.externals.joblib is deprecated in 0.21" 929 with warnings.catch_warnings(record=True) as warns: --> 930 data = tuple([joblib.load(f) for f in files]) 931 932 refresh_needed = any([str(x.message).startswith(msg) for x in warns]) /opt/conda/lib/python3.7/site-packages/sklearn/datasets/base.py in <listcomp>(.0) 928 msg = "sklearn.externals.joblib is deprecated in 0.21" 929 with warnings.catch_warnings(record=True) as warns: --> 930 data = tuple([joblib.load(f) for f in files]) 931 932 refresh_needed = any([str(x.message).startswith(msg) for x in warns]) /opt/conda/lib/python3.7/site-packages/joblib/numpy_pickle.py in load(filename, mmap_mode) 603 return load_compatibility(fobj) 604 --> 605 obj = _unpickle(fobj, filename, mmap_mode) 606 607 return obj /opt/conda/lib/python3.7/site-packages/joblib/numpy_pickle.py in _unpickle(fobj, filename, mmap_mode) 527 obj = None 528 try: --> 529 obj = unpickler.load() 530 if unpickler.compat_mode: 531 warnings.warn("The file '%s' has been generated with a " /opt/conda/lib/python3.7/pickle.py in load(self) 1083 raise EOFError 1084 assert isinstance(key, bytes_types) -> 1085 dispatch[key[0]](self) 1086 except _Stop as stopinst: 1087 return stopinst.value /opt/conda/lib/python3.7/site-packages/joblib/numpy_pickle.py in load_build(self) 353 if isinstance(array_wrapper, NDArrayWrapper): 354 self.compat_mode = True --> 355 self.stack.append(array_wrapper.read(self)) 356 357 # Be careful to register our new method. /opt/conda/lib/python3.7/site-packages/joblib/numpy_pickle.py in read(self, unpickler) 196 array = self.read_mmap(unpickler) 197 else: --> 198 array = self.read_array(unpickler) 199 200 # Manage array subclass case /opt/conda/lib/python3.7/site-packages/joblib/numpy_pickle.py in read_array(self, unpickler) 147 read_size = int(read_count * self.dtype.itemsize) 148 data = _read_bytes(unpickler.file_handle, --> 149 read_size, "array data") 150 array[i:i + read_count] = \ 151 unpickler.np.frombuffer(data, dtype=self.dtype, /opt/conda/lib/python3.7/site-packages/joblib/numpy_pickle_utils.py in _read_bytes(fp, size, error_template) 241 if len(data) != size: 242 msg = "EOF: reading %s, expected %d bytes got %d" --> 243 raise ValueError(msg % (error_template, size, len(data))) 244 else: 245 return data ValueError: EOF: reading array data, expected 262144 bytes got 209661 或其他NaN传递到本地网桥时发生的。 在我的代码中,如下所示:

Infinity

非常感谢此链接: #23835

答案 4 :(得分:0)

对我来说,发生了同样的错误,作为一种错误查找方法,我一步一步地注释了部分组件,最后找到了我犯错的地方! :

<Animatable.View   style={{marginTop:**Number(this.SearchTopMargin)**}}

类型强制转换错误:Number(this.SearchTopMargin) 并且我删除了类型转换并解决了问题:

<Animatable.View   style={{marginTop:this.SearchTopMargin}}

我需要解决将Animate值转换为数字的问题,但这是另一个问题!

答案 5 :(得分:0)

堆栈跟踪中给出的问题根本没有帮助,最终指向反应导航。在我的例子中,我设置了一个无效的属性。

答案 6 :(得分:0)

如果您在 TextInput

中输入
onChange={e => {
              setPassword(e)
            }}

确保将其更改为:

onChange={e => {
              setPassword(e.nativeEvent.text)
            }}