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

[0.65] [iOS] Redbox displayed as well as LogBox #32106

Closed
chrisgreen1993 opened this issue Aug 27, 2021 · 16 comments
Closed

[0.65] [iOS] Redbox displayed as well as LogBox #32106

chrisgreen1993 opened this issue Aug 27, 2021 · 16 comments

Comments

@chrisgreen1993
Copy link

chrisgreen1993 commented Aug 27, 2021

Description

In 0.65 on iOS, RedBox is displayed as well as LogBox when using console.error or throwing an Error.

React Native version:

System:
    OS: macOS 10.15.7
    CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
    Memory: 84.11 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 14.15.0 - ~/.nvm/versions/node/v14.15.0/bin/node
    Yarn: 1.22.10 - ~/.nvm/versions/node/v14.15.0/bin/yarn
    npm: 7.5.4 - ~/.nvm/versions/node/v14.15.0/bin/npm
    Watchman: Not Found
  Managers:
    CocoaPods: 1.10.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.0, DriverKit 19.0, macOS 10.15, tvOS 14.0, watchOS 7.0
    Android SDK: Not Found
  IDEs:
    Android Studio: 3.6 AI-192.7142.36.36.6241897
    Xcode: 12.0.1/12A7300 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.6 - /usr/local/opt/openjdk@11/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2
    react-native: 0.65.1 => 0.65.1
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. npx react-native init Test --version 0.65.1
  2. Open up App.js and add the following to App component:
    const App: () => Node = () => {
       const isDarkMode = useColorScheme() === 'dark';
       console.error('hello'); // <-- Add this here
       const backgroundStyle = {
         backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
       };
  3. run yarn start and yarn ios

Expected Results

I expect to only see the error in LogBox at the bottom of the screen as in 0.64.2:
Screenshot 2021-08-27 at 16 59 06

Actual Results

I get the Error in Redbox as well (Note that this is only an issue on iOS):

Screenshot 2021-08-27 at 16 58 42

This also happens when throwing an Error, however it isn't as much of an issue as LogBox is displayed in full screen in this case anyway.

@chrisgreen1993 chrisgreen1993 changed the title [0.65] [Android] Redbox displayed as well as LogBox [0.65] [iOS] Redbox displayed as well as LogBox Aug 27, 2021
@mrousavy
Copy link
Contributor

Shouldn't the RedBox be deprecated?

@NickGerleman
Copy link
Contributor

@mrousavy RedBox is still needed for cases where the bundle fails to load, since LogBox has not yet loaded. RedBox display is instead handled in native code.

@mrousavy
Copy link
Contributor

mrousavy commented Sep 2, 2021

Oh so the LogBox cannot be activated from native code? I tried to find an API for that to add LogBox (incl. stacktrace and source preview) support for Reanimated/VisionCamera Worklets, but seems like that's pretty difficult to achieve...

@NickGerleman
Copy link
Contributor

@mrousavy LogBox is rendered in JS using react-native, but you can inject redbox/yellowbox from native if you really want to.

Instance load registers RCTLog as a callable module, so if you have a react instance (Not sure what Java or ObjC projections of the instance look like), you can call RCTLog.logToConsole from the React Instance, with args of severity (warn or error), along with the string.

That async from native triggers the equivalent of console.warn or console.log.

@NickGerleman
Copy link
Contributor

These would likely all be considered private APIs though... So YMMV

@mrousavy
Copy link
Contributor

mrousavy commented Sep 2, 2021

thanks nick!

@anthowm
Copy link

anthowm commented Sep 14, 2021

Today I was upgrading to 0.65.2 make it works but all console.errors trigger a fullScreen LogBox. There is any workaround or plan to fix this ?

@apamphilon
Copy link

apamphilon commented Sep 23, 2021

Also in the same position as @anthowm. Does anyone know if this is being looked at?

@anthowm
Copy link

anthowm commented Sep 23, 2021

@apamphilon By the moment we put this so we can go ahead with the upgrade don't know the full impact of put this
//

* setting `console.reportErrorsAsExceptions = false;` in your app.

// @ts-ignore Disable error screen from console.error as we use it.
console.reportErrorsAsExceptions = false;

@chrisgreen1993
Copy link
Author

@apamphilon By the moment we put this so we can go ahead with the upgrade don't know the full impact of put this
//

* setting `console.reportErrorsAsExceptions = false;` in your app.

// @ts-ignore Disable error screen from console.error as we use it.
console.reportErrorsAsExceptions = false;

@anthowm This could work as a workaround for now although one thing to note with this is that it also disables LogBox for console.errors.

@christophemenager
Copy link

I have the exact same issue, after 1 hour looking for solutions, it appears this issue is the only one trying to solve this.
Does anyone found a better solution than disabling all the error logs ? (which works btw)

@valeriashpiner
Copy link

I am facing the same issue with 0.66. It would be nice to have a workaround.

@liamjones
Copy link
Contributor

Just encountered this upgrading from RN 0.63.4 to 0.66.3 myself. Only seems to affect iOS.

@liamjones
Copy link
Contributor

Oh, I forgot to post in here.

I believe I've found the original cause for this issue and I've raised a PR for the fix: #32641

If you want to fix it locally, in advance of the PR being released, it's a one-line change you could use patch-package to apply.

@christophemenager
Copy link

Thanks a lot @liamjones , created a patch for my project and it works perfectly well 👌 Nice job !

@DavinAhn
Copy link

@liamjones Thanks for finding the cause and fixing it.

I solved it with method swizzling. Since I do a lot of swizzling, this method was easy.

Just add the code below to your project.

// RCTExceptionsManager+FixBug.h
#import <React-Core/React/RCTExceptionsManager.h>

@interface RCTExceptionsManager (FixBug)

@end
// RCTExceptionsManager+FixBug.m
#import "RCTExceptionsManager+FixBug.h"

#import <objc/message.h>
#import <React-Core/React/RCTRedBox.h>

@implementation RCTExceptionsManager (FixBug)

BOOL swizzle(Class __nonnull class, SEL __nonnull originalSelector, SEL __nonnull newSelector, id __nonnull block) {
  if ([class instancesRespondToSelector:newSelector]) {
    return YES;
  }

  Method originalMethod = class_getInstanceMethod(class, originalSelector);
  IMP implementForNewSelector = imp_implementationWithBlock(block);
  if (!class_addMethod(class, newSelector, implementForNewSelector, method_getTypeEncoding(originalMethod))) {
    return NO;
  }

  Method newMethod = class_getInstanceMethod(class, newSelector);
  if (class_addMethod(class, originalSelector, method_getImplementation(newMethod), method_getTypeEncoding(originalMethod))) {
    class_replaceMethod(class, newSelector, method_getImplementation(originalMethod), method_getTypeEncoding(newMethod));
  }
  else {
    method_exchangeImplementations(originalMethod, newMethod);
  }

  NSLog(@"Swizzled [%@] %@ -> %@", NSStringFromClass(class), NSStringFromSelector(originalSelector), NSStringFromSelector(newSelector));

  return YES;
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"

+ (void)initialize {
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    SEL originSelector = @selector(updateExceptionMessage:stack:exceptionId:);
    SEL swizzleSelector = @selector(swizzle_updateExceptionMessage:stack:exceptionId:);
    swizzle([RCTExceptionsManager class], originSelector, swizzleSelector, ^(RCTExceptionsManager *manager, NSString *message, NSArray<NSDictionary *> *stack, double exceptionId) {
      RCTRedBox *redbox = [manager.moduleRegistry moduleForName:"RedBox"];
      [redbox updateErrorMessage:message withStack:stack errorCookie:(int)exceptionId];

      if (manager.delegate && [manager.delegate respondsToSelector:@selector(updateJSExceptionWithMessage:stack:exceptionId:)]) {
        [manager.delegate updateJSExceptionWithMessage:message stack:stack exceptionId:[NSNumber numberWithDouble:exceptionId]];
      }
    });
  });
}

#pragma clang diagnostic pop

@end

@facebook facebook locked as resolved and limited conversation to collaborators Jan 19, 2023
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jan 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants