/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

package com.facebook.react.modules.core;

import java.io.File;

import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.devsupport.DevSupportManager;
import com.facebook.react.common.ReactConstants;

public class ExceptionsManagerModule extends BaseJavaModule {

  private final DevSupportManager mDevSupportManager;

  public ExceptionsManagerModule(DevSupportManager devSupportManager) {
    mDevSupportManager = devSupportManager;
  }

  @Override
  public String getName() {
    return "RKExceptionsManager";
  }

  private String stackTraceToString(String message, ReadableArray stack) {
    StringBuilder stringBuilder = new StringBuilder(message).append(", stack:\n");
    for (int i = 0; i < stack.size(); i++) {
      ReadableMap frame = stack.getMap(i);
      stringBuilder
          .append(frame.getString("methodName"))
          .append("@")
          .append(frame.getInt("lineNumber"));
      if (frame.hasKey("column") &&
          !frame.isNull("column") &&
          frame.getType("column") == ReadableType.Number) {
        stringBuilder
            .append(":")
            .append(frame.getInt("column"));
      }
      stringBuilder.append("\n");
    }
    return stringBuilder.toString();
  }

  @ReactMethod
  public void reportFatalException(String title, ReadableArray details, int exceptionId) {
    showOrThrowError(title, details, exceptionId);
  }

  @ReactMethod
  public void reportSoftException(String title, ReadableArray details, int exceptionId) {
    FLog.e(ReactConstants.TAG, stackTraceToString(title, details));
  }

  private void showOrThrowError(String title, ReadableArray details, int exceptionId) {
    if (mDevSupportManager.getDevSupportEnabled()) {
      mDevSupportManager.showNewJSError(title, details, exceptionId);
    } else {
      throw new JavascriptException(stackTraceToString(title, details));
    }
  }

  @ReactMethod
  public void updateExceptionMessage(String title, ReadableArray details, int exceptionId) {
    if (mDevSupportManager.getDevSupportEnabled()) {
      mDevSupportManager.updateJSError(title, details, exceptionId);
    }
  }

  @ReactMethod
  public void dismissRedbox() {
    if (mDevSupportManager.getDevSupportEnabled()) {
      mDevSupportManager.hideRedboxDialog();
    }
  }
}

@@ -361,15 +361,58 @@
 ava.
-io.File
+util.regex.Matcher;%0Aimport java.util.regex.Pattern
 ;%0A%0Ai
@@ -856,16 +856,114 @@
 dule %7B%0A%0A
+  static private final Pattern mJsModuleIdPattern = Pattern.compile(%22(?:%5E%7C%5B/%5C%5C%5C%5C%5D)(%5C%5Cd+%5C%5C.js)$%22);%0A
   privat
@@ -1205,24 +1205,854 @@
 ager%22;%0A  %7D%0A%0A
+  // If the file name of a stack frame is numeric (+ %22.js%22), we assume it's a lazily injected module%0A  // coming from a %22random access bundle%22. We are using special source maps for these bundles, so%0A  // that we can symbolicate stack traces for multiple injected files with a single source map.%0A  // We have to include the module id in the stack for that, though. The %22.js%22 suffix is kept to%0A  // avoid ambiguities between %22module-id:line%22 and %22line:column%22.%0A  static private String stackFrameToModuleId(ReadableMap frame) %7B%0A    if (frame.hasKey(%22file%22) &&%0A        !frame.isNull(%22file%22) &&%0A        frame.getType(%22file%22) == ReadableType.String) %7B%0A      final Matcher matcher = mJsModuleIdPattern.matcher(frame.getString(%22file%22));%0A      if (matcher.find()) %7B%0A        return matcher.group(1) + %22:%22;%0A      %7D%0A    %7D%0A    return %22%22;%0A  %7D%0A%0A
   private St
@@ -2354,16 +2354,16 @@
 Name%22))%0A
-
         
@@ -2377,16 +2377,63 @@
 nd(%22@%22)%0A
+          .append(stackFrameToModuleId(frame))%0A
         

Add Random Access Module file names to stack traces