Skip to content

Commit

Permalink
fix(ios): manually evaluate all error properties (9_0_X) (#11577)
Browse files Browse the repository at this point in the history
* fix(ios): manually evaluate all error properties

* fix(ios): pass correct context argument

* fix(ios): look up non-enumerable error properties

Co-authored-by: Vijay Vikram Singh <vsingh@axway.com>
Co-authored-by: ssekhri <ssekhri@axway.com>
  • Loading branch information
3 people committed Apr 9, 2020
1 parent 2ca1f46 commit 3e06680
Show file tree
Hide file tree
Showing 13 changed files with 98 additions and 41 deletions.
6 changes: 2 additions & 4 deletions iphone/TitaniumKit/TitaniumKit/Sources/API/KrollBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,8 @@ - (void)evalFileOnThread:(NSString *)path context:(KrollContext *)context_
}
}
if (exception != NULL) {
id excm = [KrollObject toID:context value:exception];
evaluationError = YES;
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:excm]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inKrollContext:context];
}

JSStringRelease(jsCode);
Expand Down Expand Up @@ -696,8 +695,7 @@ - (KrollWrapper *)loadCommonJSModule:(NSString *)code withSourceURL:(NSURL *)sou
[eval release];

if (exception != NULL) {
id excm = [KrollObject toID:context value:exception];
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:excm]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inKrollContext:context];
return nil;
}
/*
Expand Down
3 changes: 1 addition & 2 deletions iphone/TitaniumKit/TitaniumKit/Sources/API/ObjcProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,7 @@ - (void)_fireEventToListener:(NSString *)type withObject:(id)obj listener:(JSVal
// handle an uncaught exception
JSValue *exception = listener.context.exception;
if (exception != nil) {
NSDictionary *exceptionDict = [self JSValueToNative:exception];
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:exceptionDict]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inJSContext:listener.context];
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions iphone/TitaniumKit/TitaniumKit/Sources/API/TiBindingEvent.m
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,7 @@ void TiBindingEventProcess(TiBindingRunLoop runloop, void *payload)
JSValueRef exception = NULL;
JSObjectCallAsFunction(context, (JSObjectRef)currentCallback, (JSObjectRef)eventTargetRef, 1, (JSValueRef *)&eventObjectRef, &exception);
if (exception != NULL) {
id excm = TiBindingTiValueToNSObject(context, exception);
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:excm]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inKrollContext:runloop];
}

// Note cancel bubble
Expand Down
40 changes: 21 additions & 19 deletions iphone/TitaniumKit/TitaniumKit/Sources/API/TiBindingTiValue.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@
{
JSObjectRef obj = JSValueToObject(jsContext, objRef, NULL);
JSPropertyNameArrayRef props = JSObjectCopyPropertyNames(jsContext, obj);

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];

size_t count = JSPropertyNameArrayGetCount(props);
for (size_t i = 0; i < count; i++) {
JSStringRef jsString = JSPropertyNameArrayGetNameAtIndex(props, i);
Expand All @@ -46,23 +44,30 @@
}
[jsonkey release];
}
JSPropertyNameArrayRelease(props);

// if this looks like a JS Error object, get the message
if ([dict objectForKey:@"line"] != nil && [dict objectForKey:@"column"] != nil) {
JSStringRef messageKeyRef = JSStringCreateWithUTF8CString("message");
JSStringRef stackKeyRef = JSStringCreateWithUTF8CString("stack");
JSValueRef messageRef = JSObjectGetProperty(jsContext, obj, messageKeyRef, NULL);
JSValueRef stackRef = JSObjectGetProperty(jsContext, obj, stackKeyRef, NULL);

id message = TiBindingTiValueToNSObject(jsContext, messageRef);
if (message && ![message isEqual:[NSNull null]]) {
// if this looks like a JS Error object, get related non-enumerable properties
JSContext *context = [JSContext contextWithJSGlobalContextRef:JSContextGetGlobalContext(jsContext)];
JSValue *value = [JSValue valueWithJSValueRef:objRef inContext:context];
if ([value hasProperty:@"line"] && [value hasProperty:@"column"]) {
if ([dict objectForKey:@"message"] == nil && [value hasProperty:@"message"]) {
NSString *message = [value[@"message"] toString];
[dict setObject:message forKey:@"message"];
}
JSStringRelease(messageKeyRef);

id stack = TiBindingTiValueToNSObject(jsContext, stackRef);
if (stack && ![stack isEqual:[NSNull null]]) {

if ([dict objectForKey:@"line"] == nil && [value hasProperty:@"line"]) {
NSNumber *line = [value[@"line"] toNumber];
[dict setObject:line forKey:@"line"];
}
if ([dict objectForKey:@"column"] == nil && [value hasProperty:@"column"]) {
NSNumber *column = [value[@"column"] toNumber];
[dict setObject:column forKey:@"column"];
}
if ([dict objectForKey:@"sourceURL"] == nil && [value hasProperty:@"sourceURL"]) {
NSString *sourceURL = [value[@"sourceURL"] toString];
[dict setObject:sourceURL forKey:@"sourceURL"];
}
if ([dict objectForKey:@"stack"] == nil && [value hasProperty:@"stack"]) {
NSString *stack = [value[@"stack"] toString];
// lets re-format the stack similar to node.js
stack = [stack stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"file://%@", [[NSBundle mainBundle] bundlePath]] withString:@"("];
stack = [stack stringByReplacingOccurrencesOfString:@"\n" withString:@")\n at "];
Expand All @@ -72,11 +77,8 @@

[dict setObject:stack forKey:@"stack"];
}
JSStringRelease(stackKeyRef);
}

JSPropertyNameArrayRelease(props);

return [dict autorelease];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
*/

#import <Foundation/Foundation.h>
#import <JavaScriptCore/JSValueRef.h>

@class KrollContext;
@class JSValue;
@class JSContext;

#pragma mark - TiScriptError

Expand Down Expand Up @@ -107,4 +112,8 @@

- (void)reportScriptError:(TiScriptError *)error;

- (void)reportScriptError:(JSValueRef)errorRef inKrollContext:(KrollContext *)krollContext;

- (void)reportScriptError:(JSValue *)error inJSContext:(JSContext *)context;

@end
12 changes: 12 additions & 0 deletions iphone/TitaniumKit/TitaniumKit/Sources/API/TiExceptionHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

#import "TiExceptionHandler.h"
#import "APSAnalytics.h"
#import "KrollContext.h"
#import "TiApp.h"
#import "TiBase.h"

#include <JavaScriptCore/JavaScriptCore.h>
#include <execinfo.h>
#include <signal.h>

Expand Down Expand Up @@ -80,6 +82,16 @@ - (void)reportScriptError:(TiScriptError *)scriptError
[currentDelegate handleScriptError:scriptError];
}

- (void)reportScriptError:(JSValueRef)errorRef inKrollContext:(KrollContext *)krollContext
{
[self reportScriptError:[TiUtils scriptErrorFromValueRef:errorRef inContext:krollContext.context]];
}

- (void)reportScriptError:(JSValue *)error inJSContext:(JSContext *)context
{
[self reportScriptError:[TiUtils scriptErrorFromValueRef:error.JSValueRef inContext:context.JSGlobalContextRef]];
}

- (void)showScriptError:(TiScriptError *)error
{
NSArray<NSString *> *exceptionStackTrace = [error valueForKey:@"nativeStack"];
Expand Down
2 changes: 2 additions & 0 deletions iphone/TitaniumKit/TitaniumKit/Sources/API/TiUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@ typedef enum {

+ (TiScriptError *)scriptErrorValue:(id)value;

+ (TiScriptError *)scriptErrorFromValueRef:(JSValueRef)valueRef inContext:(JSGlobalContextRef)contextRef;

+ (NSTextAlignment)textAlignmentValue:(id)alignment;

+ (NSString *)jsonStringify:(id)value;
Expand Down
43 changes: 43 additions & 0 deletions iphone/TitaniumKit/TitaniumKit/Sources/API/TiUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,49 @@ + (WebFont *)fontValue:(id)value
return [self fontValue:value def:[WebFont defaultFont]];
}

+ (TiScriptError *)scriptErrorFromValueRef:(JSValueRef)valueRef inContext:(JSGlobalContextRef)contextRef
{
JSContext *context = [JSContext contextWithJSGlobalContextRef:contextRef];
JSValue *error = [JSValue valueWithJSValueRef:valueRef inContext:context];
NSMutableDictionary *errorDict = [NSMutableDictionary new];

if ([error hasProperty:@"constructor"]) {
[errorDict setObject:[error[@"constructor"][@"name"] toString] forKey:@"type"];
}

// error message
if ([error hasProperty:@"message"]) {
[errorDict setObject:[error[@"message"] toString] forKey:@"message"];
}
if ([error hasProperty:@"nativeReason"]) {
[errorDict setObject:[error[@"nativeReason"] toString] forKey:@"nativeReason"];
}

// error location
if ([error hasProperty:@"sourceURL"]) {
[errorDict setObject:[error[@"sourceURL"] toString] forKey:@"sourceURL"];
}
if ([error hasProperty:@"line"]) {
[errorDict setObject:[error[@"line"] toNumber] forKey:@"line"];
}
if ([error hasProperty:@"column"]) {
[errorDict setObject:[error[@"column"] toNumber] forKey:@"column"];
}

// stack trace
if ([error hasProperty:@"backtrace"]) {
[errorDict setObject:[error[@"backtrace"] toString] forKey:@"backtrace"];
}
if ([error hasProperty:@"stack"]) {
[errorDict setObject:[error[@"stack"] toString] forKey:@"stack"];
}
if ([error hasProperty:@"nativeStack"]) {
[errorDict setObject:[error[@"nativeStack"] toString] forKey:@"nativeStack"];
}

return [[[TiScriptError alloc] initWithDictionary:errorDict] autorelease];
}

+ (TiScriptError *)scriptErrorValue:(id)value;
{
if ((value == nil) || (value == [NSNull null])) {
Expand Down
3 changes: 1 addition & 2 deletions iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollCallback.m
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ - (id)call:(NSArray *)args thisObject:(id)thisObject_
JSValueRef exception = NULL;
JSValueRef retVal = JSObjectCallAsFunction(jsContext, function, tp, [args count], _args, &exception);
if (exception != NULL) {
id excm = [KrollObject toID:context value:exception];
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:excm]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inKrollContext:context];
}
if (top != NULL) {
JSValueUnprotect(jsContext, tp);
Expand Down
6 changes: 2 additions & 4 deletions iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollContext.m
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,7 @@ - (void)invoke:(KrollContext *)context
[self jsInvokeInContext:context exception:&exception];

if (exception != NULL) {
id excm = [KrollObject toID:context value:exception];
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:excm]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inKrollContext:context];
pthread_mutex_unlock(&KrollEntryLock);
}
pthread_mutex_unlock(&KrollEntryLock);
Expand All @@ -549,8 +548,7 @@ - (id)invokeWithResult:(KrollContext *)context
JSValueRef result = [self jsInvokeInContext:context exception:&exception];

if (exception != NULL) {
id excm = [KrollObject toID:context value:exception];
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:excm]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inKrollContext:context];
pthread_mutex_unlock(&KrollEntryLock);
}
pthread_mutex_unlock(&KrollEntryLock);
Expand Down
6 changes: 2 additions & 4 deletions iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -1043,8 +1043,7 @@ - (void)invokeCallbackForKey:(NSString *)key withObject:(NSDictionary *)eventDat
JSValueRef jsEventData = ConvertIdTiValue(context, eventData);
JSValueRef result = JSObjectCallAsFunction(jsContext, jsCallback, [_thisObject jsobject], 1, &jsEventData, &exception);
if (exception != NULL) {
id excm = [KrollObject toID:context value:exception];
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:excm]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inKrollContext:context];
}

if (block != nil) {
Expand Down Expand Up @@ -1279,8 +1278,7 @@ - (void)triggerEvent:(NSString *)eventName withObject:(NSDictionary *)eventData
JSValueRef exception = NULL;
JSObjectCallAsFunction(jsContext, (JSObjectRef)currentCallback, [thisObject jsobject], 1, &jsEventData, &exception);
if (exception != NULL) {
id excm = [KrollObject toID:context value:exception];
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:excm]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inKrollContext:context];
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ - (void)timerFired:(NSTimer *_Nonnull)timer
JSContext *context = self.callback.context;
JSValue *exception = context.exception;
if (exception != nil) {
NSDictionary *exceptionDict = TiBindingTiValueToNSObject(context.JSGlobalContextRef, exception.JSValueRef);
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:exceptionDict]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inJSContext:context];
}
}

Expand Down
3 changes: 1 addition & 2 deletions iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollWrapper.m
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ - (JSValueRef)executeWithArguments:(NSArray<id> *)arguments
JSValueRef functionResult = JSObjectCallAsFunction(context, value, NULL, 1, callArgs, &callException);

if (callException != NULL) {
id exceptionPayload = [KrollObject toID:self.bridge.krollContext value:callException];
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:exceptionPayload]];
[TiExceptionHandler.defaultExceptionHandler reportScriptError:callException inKrollContext:self.bridge.krollContext];
}

return functionResult;
Expand Down

0 comments on commit 3e06680

Please sign in to comment.