You attempted to set the key timestamp
with the value xxx
on an object that is meant to be immutable and has been frozen.
I haven't seen this before today and I don't think we've really changed much so maybe it is some kind of race condition. We're just calling startTabBasedApp with a config. I did a console.log(Object.isFrozen(config)) and it said false.
Update: seeing it pretty often today. Printing out the stuff from that line 119, params.passProps === undefined, and Object.isFrozen(params.passProps) === true, although Object.isFrozen(params) === false.
The params does appear to be our config to startTabBasedApp.
ExceptionsManager.js:73
{tabs: Array(5), tabsStyle: {鈥, appStyle: {鈥, animationType: "fade", passProps: {鈥}
animationType
:
"fade"
appStyle
:
forceTitlesDisplay
:
(...)
keepStyleAcrossPush
:
(...)
orientation
:
(...)
tabBarButtonColor
:
(...)
tabBarLabelColor
:
(...)
tabBarSelectedButtonColor
:
(...)
tabBarSelectedLabelColor
:
(...)
get forceTitlesDisplay
:
茠 ()
set forceTitlesDisplay
:
茠 ()
get keepStyleAcrossPush
:
茠 ()
set keepStyleAcrossPush
:
茠 ()
get orientation
:
茠 ()
set orientation
:
茠 ()
get tabBarButtonColor
:
茠 ()
set tabBarButtonColor
:
茠 ()
get tabBarLabelColor
:
茠 ()
set tabBarLabelColor
:
茠 ()
get tabBarSelectedButtonColor
:
茠 ()
set tabBarSelectedButtonColor
:
茠 ()
get tabBarSelectedLabelColor
:
茠 ()
set tabBarSelectedLabelColor
:
茠 ()
__proto__
:
Object
passProps
:
timestamp
:
(...)
get timestamp
:
茠 ()
set timestamp
:
茠 ()
__proto__
:
Object
tabs
:
Array(5)
0
:
{screen: "T", icon: 32, label: "T", navigationParams: {鈥, passProps: {鈥}
1
:
{screen: "I", icon: 33, label: "I", navigationParams: {鈥, passProps: {鈥}
2
:
{screen: "O", icon: 34, label: "O", navigationParams: {鈥, passProps: {鈥}
3
:
{screen: "P", icon: 35, label: "P", navigationParams: {鈥, passProps: {鈥}
4
:
{screen: "E", icon: 36, label: "E", navigationParams: {鈥, passProps: {鈥}
length
:
5
__proto__
:
Array(0)
tabsStyle
:
{tabBarButtonColor: "#8E8E93", tabBarLabelColor: "#8E8E93", tabBarSelectedButtonColor: "#007AFF", tabBarSelectedLabelColor: "#007AFF"}
__proto__
:
Object
reactConsoleErrorHandler | @ | ExceptionsManager.js:73
-- | -- | --
聽 | console.error | @ | YellowBox.js:71
聽 | startTabBasedApp$ | @ | platformSpecificDeprecated.ios.js:126
聽 | tryCatch | @ | runtime.js:62
聽 | invoke | @ | runtime.js:296
聽 | prototype.(anonymous function) | @ | runtime.js:114
聽 | tryCatch | @ | runtime.js:62
聽 | invoke | @ | runtime.js:152
聽 | (anonymous) | @ | runtime.js:195
聽 | tryCallTwo | @ | core.js:45
聽 | doResolve | @ | core.js:200
聽 | Promise | @ | core.js:66
聽 | callInvokeWithMethodAndArg | @ | runtime.js:194
聽 | enqueue | @ | runtime.js:217
聽 | prototype.(anonymous function) | @ | runtime.js:114
聽 | runtime.async | @ | runtime.js:241
聽 | startTabBasedApp | @ | platformSpecificDeprecated.ios.js:17
聽 | startTabBasedApp$ | @ | Navigation.js:135
聽 | tryCatch | @ | runtime.js:62
聽 | invoke | @ | runtime.js:296
聽 | prototype.(anonymous function) | @ | runtime.js:114
聽 | tryCatch | @ | runtime.js:62
聽 | invoke | @ | runtime.js:152
聽 | (anonymous) | @ | runtime.js:195
聽 | tryCallTwo | @ | core.js:45
聽 | doResolve | @ | core.js:200
聽 | Promise | @ | core.js:66
聽 | callInvokeWithMethodAndArg | @ | runtime.js:194
聽 | enqueue | @ | runtime.js:217
聽 | prototype.(anonymous function) | @ | runtime.js:114
聽 | runtime.async | @ | runtime.js:241
聽 | startTabBasedApp | @ | Navigation.js:134
聽 | startAuthenticatedApp | @ | Screens.js:223
So far, I think I've only seen it on the iOS simulator. The iPhone 6 / iOS 10.3.2 i test on hasn't failed with that yet.
dang it, nope, still get the unhandled promise rejection.
.
.
.
old incorrect claim:
fwiw If I manually patch the code from
_.set(params, 'passProps.timestamp', Date.now());
to
if (params.passProps === undefined) { params.passProps = {}; }
params.passProps.timestamp = Date.now();
then it doesn't fail.
(I did some testing in a repl of _.set() and could not repro the issue that way.)
I fixed it in our own code, it appears to be something about how module-level variables are somewhere frozen by something. So I moved the config to be inside the same function that calls startTabBasedApp and it was all ok.
@jslz For the sake of others, can you clarify what exactly you did to fix this (with code samples)? I'm running into this same exact issue.
@tmaly1980 dunno exactly other than making everything as "function local" instead of anything being "module local" helped fix it, empirically speaking.
Sorry, can you please clarify what you mean by an example? I don't know what 'function local' and 'module local' means.
@jslz I think I figured it out. I don't exactly know why, but because I call startTabBasedApp multiple times (once post-login, and another after rehydrating), passProps gets set as immutable (probably somewhere deep inside react-native-navigation)... and won't be able to be called multiple times if state changes. Apparently, it caches the object from the import statement and probably directly modifies it and will stay that way forever.
The easiest solution I could come up with is doing a deep copy using JSON:
Navigation.startTabBasedApp(JSON.parse(JSON.stringify(tabNavigationConfig)));
This solved my immutability problems with starting the app.
Just in case someone else hits this down the road, you can also have your config be returned via function to fix this:
const config = () => {
return {
tabs: [ ... ]
}
};
Navigation.startTabBasedApp(config());
I had the same problem. You @tmaly1980, just Saved My Life 馃挴
Most helpful comment
@jslz I think I figured it out. I don't exactly know why, but because I call startTabBasedApp multiple times (once post-login, and another after rehydrating), passProps gets set as immutable (probably somewhere deep inside react-native-navigation)... and won't be able to be called multiple times if state changes. Apparently, it caches the object from the import statement and probably directly modifies it and will stay that way forever.
The easiest solution I could come up with is doing a deep copy using JSON:
Navigation.startTabBasedApp(JSON.parse(JSON.stringify(tabNavigationConfig)));
This solved my immutability problems with starting the app.