Remote Connection like Browser Toolbox - firefox-addon

I'm trying to interact with another open profile, which is a seperate process. Browser Toolbox does this. I was wondering how can I re-simulate this behavior? Without the prompt asking for "allow remote connection"?
My goal is to (1) find all open firefox process, (2) access each of its xpcom and figure out the profile name, (3) and if its a profile name Im interested in, Ill focus its most recent window.

I don't know but I'm getting somewhere by tracing it in MXR:
http://mxr.mozilla.org/mozilla-release/source/browser/devtools/framework/toolbox-process-window.js#11
11 let { debuggerSocketConnect, DebuggerClient } =
12 Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
13 let { ViewHelpers } =
14 Cu.import("resource:///modules/devtools/ViewHelpers.jsm", {});
15
16 /**
17 * Shortcuts for accessing various debugger preferences.
18 */
19 let Prefs = new ViewHelpers.Prefs("devtools.debugger", {
20 chromeDebuggingHost: ["Char", "chrome-debugging-host"],
21 chromeDebuggingPort: ["Int", "chrome-debugging-port"]
22 });
23
24 let gToolbox, gClient;
25
26 function connect() {
27 window.removeEventListener("load", connect);
28 // Initiate the connection
29 let transport = debuggerSocketConnect(
30 Prefs.chromeDebuggingHost,
31 Prefs.chromeDebuggingPort
32 );
33 gClient = new DebuggerClient(transport);
34 gClient.connect(() => {
35 let addonID = getParameterByName("addonID");
36
37 if (addonID) {
38 gClient.listAddons(({addons}) => {
39 let addonActor = addons.filter(addon => addon.id === addonID).pop();
40 openToolbox({ addonActor: addonActor.actor, title: addonActor.name });
41 });
42 } else {
43 gClient.listTabs(openToolbox);
44 }
45 });
46 }
47
I ran the profile and it looks like the pref ..-host is localhost and ..-port is 6080. I'm not sure how this helps target a specific profile though. Maybe on start of the browser toolbox it opened port 6080 to the opener profile. I'm not sure, but if its true, then you'll have to run code from within the target profile to open a port maybe.
Totally not sure though.
But port is opened here:
http://mxr.mozilla.org/mozilla-release/source/browser/devtools/framework/ToolboxProcess.jsm#107
106
107 BrowserToolboxProcess.prototype = {
108 /**
109 * Initializes the debugger server.
110 */
111 _initServer: function() {
112 dumpn("Initializing the chrome toolbox server.");
113
114 if (!this.loader) {
115 // Create a separate loader instance, so that we can be sure to receive a
116 // separate instance of the DebuggingServer from the rest of the devtools.
117 // This allows us to safely use the tools against even the actors and
118 // DebuggingServer itself, especially since we can mark this loader as
119 // invisible to the debugger (unlike the usual loader settings).
120 this.loader = new DevToolsLoader();
121 this.loader.invisibleToDebugger = true;
122 this.loader.main("devtools/server/main");
123 this.debuggerServer = this.loader.DebuggerServer;
124 dumpn("Created a separate loader instance for the DebuggerServer.");
125
126 // Forward interesting events.
127 this.debuggerServer.on("connectionchange", this.emit.bind(this));
128 }
129
130 if (!this.debuggerServer.initialized) {
131 this.debuggerServer.init();
132 this.debuggerServer.addBrowserActors();
133 dumpn("initialized and added the browser actors for the DebuggerServer.");
134 }
135
136 this.debuggerServer.openListener(Prefs.chromeDebuggingPort);
137
138 dumpn("Finished initializing the chrome toolbox server.");
139 dumpn("Started listening on port: " + Prefs.chromeDebuggingPort);
140 },
141

Related

Ktor httpclient auth feature not working on IOS

I am developing a KMM project and the authentication works well on the Android app. However when I added the Auth feature in the httpclient (located in the shared.commonMain) the ios app failled at runtime with the following message
Function doesn't have or inherit #Throws annotation and thus exception isn't propagated from Kotlin to Objective-C/Swift as NSError.
It is considered unexpected and unhandled instead. Program will be terminated.
This is how I create the httpclient
private val httpclient = HttpClient() {
engine {
pipelining = true
threadsCount = 4
}
install(Logging) {
level = LogLevel.HEADERS
logger = object : Logger {
override fun log(message: String) {
Napier.v(tag = "HTTP Client", message = message)
}
}
}
install(JsonFeature) {
val json = Json { ignoreUnknownKeys = true }
serializer = KotlinxSerializer(json)
}
install(Auth) {
basic {
credentials {
BasicAuthCredentials(username = emailUser, password = passwordUser)
}
}
}
}.also {
initLogger()
}
Here is the complete code of the Greeting class:
class Greeting {
private var emailUser: String = ""
private var passwordUser: String = ""
private val httpclient = HttpClient() {
engine {
pipelining = true
threadsCount = 4
}
install(Logging) {
level = LogLevel.HEADERS
logger = object : Logger {
override fun log(message: String) {
Napier.v(tag = "HTTP Client", message = message)
}
}
}
install(JsonFeature) {
val json = Json { ignoreUnknownKeys = true }
serializer = KotlinxSerializer(json)
}
install(Auth) {
basic {
credentials {
BasicAuthCredentials(username = emailUser, password = passwordUser)
}
}
}
}.also {
initLogger()
}
#Throws(Exception::class)
suspend fun getVaccines(): List<Vaccine> {
return httpclient.get(endpointBase + Vaccine.path)
}
#Throws(Exception::class)
suspend fun loginUser(email: String, password: String): String? {
emailUser = email
passwordUser = password
return httpclient.get(endpointBase + User.path + "/userPage")
}
}
Exception full stacktrace
Function doesn't have or inherit #Throws annotation and thus exception isn't propagated from Kotlin to Objective-C/Swift as NSError.
It is considered unexpected and unhandled instead. Program will be terminated.
Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen com.example.vaccinationcertificate_mobileapp.Greeting#3963788
at 0 iosApp 0x000000010c1f728f kfun:kotlin.Throwable#<init>(kotlin.String?){} + 95
at 1 iosApp 0x000000010c1efbbd kfun:kotlin.Exception#<init>(kotlin.String?){} + 93
at 2 iosApp 0x000000010c1efe2d kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 93
at 3 iosApp 0x000000010c2272fd kfun:kotlin.native.concurrent.InvalidMutabilityException#<init>(kotlin.String){} + 93
at 4 iosApp 0x000000010c228aff ThrowInvalidMutabilityException + 431
at 5 iosApp 0x000000010c3db2c0 MutationCheck + 128
at 6 iosApp 0x000000010c151165 kfun:com.example.vaccinationcertificate_mobileapp.Greeting#<init>(){} + 437
at 7 iosApp 0x000000010c17c9de objc2kotlin.883 + 142
at 8 iosApp 0x000000010c150fa3 $sSo14SharedGreetingCABycfcTO + 19
at 9 iosApp 0x000000010c14f0af $sSo14SharedGreetingCABycfC + 31
at 10 iosApp 0x000000010c150596 $s6iosApp11ContentViewVACycfC + 38 (/Users/oprisvlad2/projects/VaccinationCertificate/VaccinationCertificate-mobileapp/iosApp/iosApp/ContentView.swift:4:0)
at 11 iosApp 0x000000010c14ebf3 $s6iosApp6iOSAppV4bodyQrvgAA11ContentViewVyXEfU_ + 35 (/Users/oprisvlad2/projects/VaccinationCertificate/VaccinationCertificate-mobileapp/iosApp/iosApp/iOSApp.swift:7:4)
at 12 iosApp 0x000000010c14eda0 $s6iosApp11ContentViewVIgo_ACIegr_TR + 16
at 13 iosApp 0x000000010c14edd1 $s6iosApp11ContentViewVIgo_ACIegr_TRTA + 17
at 14 SwiftUI 0x00000001173612cf $s7SwiftUI11WindowGroupV7contentACyxGxyXE_tcfC + 63
at 15 iosApp 0x000000010c14eac5 $s6iosApp6iOSAppV4bodyQrvg + 181 (/Users/oprisvlad2/projects/VaccinationCertificate/VaccinationCertificate-mobileapp/iosApp/iosApp/iOSApp.swift:6:3)
at 16 iosApp 0x000000010c14ef79 $s6iosApp6iOSAppV7SwiftUI0B0AadEP4body4BodyQzvgTW + 9
at 17 SwiftUI 0x0000000116dce845 $s7SwiftUI15AppBodyAccessor33_A363922CEBDF47986D9772B903C8737ALLV06updateD02of7changedyx_SbtF0D0QzyXEfU_TA + 22
at 18 SwiftUI 0x0000000117357449 $s7SwiftUI12BodyAccessorPAAE03setC0yy0C0QzyXEFAFyXEfU_ + 34
at 19 SwiftUI 0x0000000116dce174 $s7SwiftUI15AppBodyAccessor33_A363922CEBDF47986D9772B903C8737ALLV06updateD02of7changedyx_SbtF + 1310
at 20 SwiftUI 0x00000001173575ac $s7SwiftUI10StaticBody33_49D2A32E637CD497C6DE29B8E060A506LLV11updateValueyyF + 161
at 21 SwiftUI 0x000000011754055c $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA12StatefulRuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_TA + 26
at 22 AttributeGraph 0x0000000110585e9b _ZN2AG5Graph11UpdateStack6updateEv + 553
at 23 AttributeGraph 0x0000000110586491 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
at 24 AttributeGraph 0x000000011058c491 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 299
at 25 AttributeGraph 0x00000001105a2889 AGGraphGetValue + 210
at 26 SwiftUI 0x00000001173574d5 $s7SwiftUI10StaticBody33_49D2A32E637CD497C6DE29B8E060A506LLV9container9ContainerQzvg + 67
at 27 SwiftUI 0x0000000117357599 $s7SwiftUI10StaticBody33_49D2A32E637CD497C6DE29B8E060A506LLV11updateValueyyF + 142
at 28 SwiftUI 0x000000011754055c $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA12StatefulRuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_TA + 26
at 29 AttributeGraph 0x0000000110585e9b _ZN2AG5Graph11UpdateStack6updateEv + 553
Exact solution:
moved emailUser and passwordUser in commonMain.Platform
expect var emailUser: String
expect var passwordUser: String
androidMain.Platform
actual var emailUser = ""
actual var passwordUser = ""
iosMain.Platform
actual var emailUser: String = AtomicReference("").value
actual var passwordUser: String = AtomicReference("").value
You need to check out how kotlin-native concurrent-mutability works
In short, you can't use any var in your shared code, that may be accessed from different threads. You had to wrap those values with Atomic containers. Replace both emailUser and passwordUser with something like this:
private val emailUser = Atomic("")
private val passwordUser = Atomic("")
Also you can use delegated-properties so you don't need to write .value each time
There's no Atomic declarations for common code, so you have to do you by yourself. In actual for iOS you can use native atomics and for android just make a simple wrapped.
Good news is that this won't stay for long, as JetBrains is planning to change concurrency model soon before KMP release. But for now we had to deal with it.
Ok, for inattentive guys like me I leave a fix for described issue with ktor.
Do not forget to add
dependencies {
implementation("io.ktor:ktor-client-darwin:$ktorVersion")
}
to iosMain section in build.gradle.kts for shared module.
Don't mix it with iosTest for example!
So you will have something like this:
val iosMain by creating {
dependencies {
implementation("io.ktor:ktor-client-darwin:$ktorVersion")
}
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}

icinga2 - where to change client monitoring commands?

system ubuntu 16.04
On master node where icinga2 is installed
#ls /etc/icinga2/repository.d/hosts/WIN-U52321E0BAK/
disk C%3A.conf disk.conf icinga.conf load.conf ping4.conf
ping6.conf procs.conf swap.conf users.conf
All conf files have save "dummy" check_command on them for example
#cat load.conf
object Service "load" {
import "satellite-service"
check_command = "dummy"
host_name = "WIN-U52321E0BAK"
zone = "WIN-U52321E0BAK"
}
I cant understand from where dummy command is called and how to customize the checks for warning and critical threshold
The dummy command is defined in /usr/share/icinga2/include/command-plugins.conf, like so:
144 object CheckCommand "dummy" {
145 import "plugin-check-command"
146
147 command = [
148 PluginDir + "/check_dummy",
149 "$dummy_state$",
150 "$dummy_text$"
151 ]
152
153 vars.dummy_state = 0
154 vars.dummy_text = "Check was successful."
155 }
In order to modify the warn and crit levels, you set the custom variable at the host or service level. Using the example of ping, we see the default configuration in that same file:
36 template CheckCommand "ping-common" {
37 import "plugin-check-command"
38
39 command = [ PluginDir + "/check_ping" ]
40
41 arguments = {
42 "-H" = "$ping_address$"
43 "-w" = "$ping_wrta$,$ping_wpl$%"
44 "-c" = "$ping_crta$,$ping_cpl$%"
45 "-p" = "$ping_packets$"
46 "-t" = "$ping_timeout$"
47 }
48
49 vars.ping_wrta = 100
50 vars.ping_wpl = 5
51 vars.ping_crta = 200
52 vars.ping_cpl = 15
53 }
Here's the important bit:
49 vars.ping_wrta = 100
50 vars.ping_wpl = 5
51 vars.ping_crta = 200
52 vars.ping_cpl = 15
So: we go to our host or service definition, thusly (using /etc/icinga2/conf.d/host.conf and the NodeName/localhost definition which everybody has; comments removed):
18 object Host NodeName {
20 import "generic-host"
21
23 address = "127.0.0.1"
24 address6 = "::1"
25
27 vars.os = "Linux"
30 vars.http_vhosts["http"] = {
31 http_uri = "/"
32 }
37
39 vars.disks["disk"] = {
41 }
42 vars.disks["disk /"] = {
43 disk_partitions = "/"
44 }
45 }
And we insert before line 45 above to produce:
18 object Host NodeName {
20 import "generic-host"
21
23 address = "127.0.0.1"
24 address6 = "::1"
25
27 vars.os = "Linux"
30 vars.http_vhosts["http"] = {
31 http_uri = "/"
32 }
37
39 vars.disks["disk"] = {
41 }
42 vars.disks["disk /"] = {
43 disk_partitions = "/"
44 }
45 vars.ping_wrta = 50
46 vars.ping_wpl = 3
47 vars.ping_crta = 10
48 vars.ping_cpl = 2
49 }
...and you have successfully customized the check threshold. You can add those variables to a template or even a hostgroup (I think; better test that, I may be wrong).

Watch app starts with error clientIdentifier for interfaceControllerID not found

I'm having a smartwatch app on watchos2. The app always worked but now when it starts I immediately get this error:
Lop_WatchKit_Extension[17535:7854201] *********** ERROR -[SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier for interfaceControllerID:447E0002 not found
I found some topics here on stackoverflow but nothing solved the problem.
In my case, this was due to a retain cycle in one InterfaceController of mine.
If you get the logs similar to:
[default] -[SPRemoteInterface
_interfaceControllerClientIDForControllerID:]:0000: ComF: clientIdentifier for interfaceControllerID:XXXXXXXX not found
&/or...
[default] _SendRecordedValues:000: ComF:<-Plugin controller ID
XXXXXXXX has no client identifier
First, figure out which InterfaceController has the controller ID XXXXXXXX.
Have this in awake(withContext:)
override func awake(withContext context: Any?) {
//...
if let id = self.value(forKey: "_viewControllerID") as? NSString {
let strClassDescription = String(describing: self)
print("\(strClassDescription) has the Interface Controller ID \(id)")
}
//...
}
This logs:
[Target.Classname: 0xYYYYYYYY] has the Interface Controller ID
XXXXXXXX
Once you identify the InterfaceController causing these logs, you can continue to debug.
It could be different in your case but in mine I had created a retain cycle with self in one of my closures within which took awhile to locate but I eventually broke the retain cycle with a [weak self] capture.
Basically, the error logs appear when an InterfaceController is trying to execute some code but it has already been released.
What I already had:
DispatchQueue.main.async {
self.doSomethingThatDoesSomethingAsync()
}
What I fixed:
DispatchQueue.main.async { [weak self] in
self?.doSomethingThatDoesSomethingAsync()
}
If you use didSet on any IBOutlets it will also throw this error in the logs.
class MyInterfaceController: WKInterfaceController {
#IBOutlet var myLabel: WKInterfaceLabel! {
didSet {
myLabel.setTitle("Test")
}
}
How #nickromano sad, it's happens when you use didSet with IBOutlets. Cause it's calls before awake(withContext context: Any?)
We can suppress this error if wrap it in DispatchQueue.main.async
#IBOutlet var statusLabel: WKInterfaceLabel! {
didSet {
DispatchQueue.main.async {
self.statusLabel.setHidden(true)
}
}
This has happened to me a few times and more times than not, it is because of a timer that is still firing in a just-previously dismissed WKInterfaceController that I did not catch.
Best thing to do aside from comparing ID's like in #staticVoidMan's answer is to read the call stack. In my case I was able to identify that the old timer was still firing based off these hints:
8 Foundation 0x00007fff214be867 __NSFireTimer + 67
9 CoreFoundation 0x00007fff207a8e3f __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
10 CoreFoundation 0x00007fff207a8912 __CFRunLoopDoTimer + 926
Here is the original call stack (for reference):
<MyApp.InterfaceController: 0x7fb3e4d2d020> has the Interface Controller ID 1EB00002
2021-05-26 14:44:06.632758-0600 MyApp WatchKit Extension[73392:3546879] [default] -[SPRemoteInterface _interfaceControllerClientIDForControllerID:]:2464: ComF: clientIdentifier for interfaceControllerID:1EB00007 not found. callStack:(
0 WatchKit 0x00007fff38d1a268 -[SPRemoteInterface _interfaceControllerClientIDForControllerID:] + 220
1 WatchKit 0x00007fff38d1bfff __54+[SPRemoteInterface setController:key:property:value:]_block_invoke + 340
2 WatchKit 0x00007fff38d12323 spUtils_dispatchAsyncToMainThread + 30
3 WatchKit 0x00007fff38d1be60 +[SPRemoteInterface setController:key:property:value:] + 179
4 WatchKit 0x00007fff38d057af -[WKInterfaceObject _sendValueChanged:forProperty:] + 706
5 WatchKit 0x00007fff38d2a5f8 -[WKInterfaceObject _setImage:forProperty:] + 50
6 MyApp WatchKit Extension 0x000000010955531d $s26MyApp_WatchKit_Extension25ActivityIndicatorDelegateC06handleE5TimeryyF + 813
7 MyApp WatchKit Extension 0x000000010955537a $s26MyApp_WatchKit_Extension25ActivityIndicatorDelegateC06handleE5TimeryyFTo + 42
8 Foundation 0x00007fff214be867 __NSFireTimer + 67
9 CoreFoundation 0x00007fff207a8e3f __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
10 CoreFoundation 0x00007fff207a8912 __CFRunLoopDoTimer + 926
11 CoreFoundation 0x00007fff207a7ec5 __CFRunLoopDoTimers + 265
12 CoreFoundation 0x00007fff207a2546 __CFRunLoopRun + 1949
13 CoreFoundation 0x00007fff207a18be CFRunLoopRunSpecific + 567
14 GraphicsServices 0x00007fff25b49fd3 GSEventRunModal + 139
15 UIKitCore 0x00007fff43290f24 -[UIApplication _run] + 917
16 UIKitCore 0x00007fff43295c0b UIApplicationMain + 101
17 WatchKit 0x00007fff38d0de65 WKExtensionMain + 800
18 libdyld.dylib 0x00007fff20202db5 start + 1
19 ??? 0x0000000000000001 0x0 + 1
)
Have you changed the name of your module? If this is the case then you have to go through your storyboard and update it manually for all the Interfaces you have.
Edit with steps to fix:
Go to the storyboard and for each interface open the Identity inspector, then delete what's in Module and press enter, the new module should get auto-filled.

why when exiting a Dart async Future is the following error not being caught (correctly)?

I have a problem using Dart postgresql database driver (xxgreg on Github) insofar as when the postgresql server is not running and it needs to be, I am unable to correctly handle the error. I’ve attempted to solve this for a while now, so any help would be appreciated. I can easily work around it by handling it silently and simply testing if the database connection object is null, however I think it should be possible to handle the raising of an error. It should be noted that when the Postgresql server is running, there is no problem.
The error that I am getting is as follows :
“Uncaught Error: Exception: fConnectToDb: Database is not connected
Stack Trace: ………….”
The problem area relates to these lines of code : (Line 663 is called from line 169 below)
663 async.Future<bool> fConnectToDb(String sUri) {
664 async.Completer<bool> oCompleter = new async.Completer<bool>();
665
666 pg.connect(sUri)
667 .catchError((oError) {
668 String sErrorMsg = (oError is SocketException) ?
669 "Database is not connected"
670 : "Fatal error encountered ${oError}";
671 throw("fConnectToDb: ${sErrorMsg}");
//(expanded below)
I have previously encountered problems in this area where at line 671, instead of throwing an exception, I called an internal method which displayed an error, and terminated the program. I found however what appeared to be a problem doing that, and I found in that situation, throwing an error enabled the program to exit the Future method, and not doing that appeared to be the problem. The problem may relate to the Future not being completed, but I don’t know how to do that and also throw an exception.
The overall code in-question is as follows. I put a try at line 167… 406, however that doesn’t catch the error either.
164 /*
165 * Connect to database
166 */
167 try {
168 sCheckpoint = "Connect to Database";
169 fConnectToDb(sUri)
170 .catchError((oError) =>
171 fFatal(sCheckpoint, "Error = \n${oError}"))
172 .then((_) {
173 if (ogDb == null) // ogDb is global object for db connection
174 fFatal(sCheckpoint, "Database did not connect");
175
176 /*
177 * Perform an SQL Select to test connection
178 */
179 ogPrintLine.fPrintForce("Testing Db connection .....");
180 sCheckpoint = "test connection";
181 return fProcessSqlSelect ("SELECT count(*) FROM ${S_TABLE_NAME}",
182 false);
183 }).then((llResult) {
184
…………
…………
// (catch related to line 167)
406 } catch(oError) {fFatal("Program Main()",
407 "Checkpoint ${sCheckpoint}, Error = \n${oError}");}
408 }
………..
………..
660 /*
661 * Connect To Database
662 */
663 async.Future<bool> fConnectToDb(String sUri) {
664 async.Completer<bool> oCompleter = new async.Completer<bool>();
665
666 pg.connect(sUri)
667 .catchError((oError) {
668 String sErrorMsg = (oError is SocketException) ?
669 "Database is not connected"
670 : "Fatal error encountered ${oError}";
671 throw("fConnectToDb: ${sErrorMsg}");
672
673 }).then((pg.Connection oDb) {
674 ogDb = oDb;
675 oCompleter.complete(true);
676 return;
677
678 });
679
680 return oCompleter.future;
681 }
As far as I can determine, it appears to me that it's Ok to throw an error in a Future providing it's followed by a catchError() that doesn't throw an error.
The following code appears to solve the problem that I was having :
/*
* Connect To Database
*/
async.Future<bool> fConnectToDb(String sUri) {
async.Completer<bool> oCompleter = new async.Completer<bool>();
pg.connect(sUri).then((pg.Connection oDb) {
ogDb = oDb; // assign to global database object
oCompleter.complete(true);
return;
}).catchError((oError) =>
fFatal("fConnectToDb", "Error=\n${oError}"));
return oCompleter.future;
}

why is code not executing on return from Future in Dart program

Could someone please explain to me why in the following code (using r25630 Windows), the value of iInsertTot at line 241 is null, or more to the point, why is line 234 ("return iInsertTot;") not executed and therefore at line 241, iInsertTot is null. The value of iInsertTot at lines 231/232 is an integer. While I can and probably should code this differently, I thought that I would try and see if it worked, because my understanding of Futures and Chaining was that it would work. I have used “return” in a similar way before and it worked, but I was returning null in those cases (eg. line 201 below).
/// The problem lines are :
233 fUpdateTotalsTable().then((_) {
234 return iInsertTot;
235 });
While running in the debugger, it appears that line 234 “return iInsertTot;” is never actually executed. Running from command line has the same result.
The method being called on line 233 (fUpdateTotalsTable) is something I am just in the process of adding, and it consists basically of sync code at this stage. However, the debugger appears to go through it correctly.
I have included the method “fUpdateTotalsTable()” (line 1076) just in case that is causing a problem.
Lines 236 to 245 have just been added, however just in case that code is invalid I have commented those lines out and run with the same problem occurring.
218 /*
219 * Process Inserts
220 */
221 }).then((_) {
222 sCheckpoint = "fProcessMainInserts";
223 ogPrintLine.fPrintForce ("Processing database ......");
224 int iMaxInserts = int.parse(lsInput[I_MAX_INSERTS]);
225 print ("");
226 return fProcessMainInserts(iMaxInserts, oStopwatch);
227 /*
228 * Update the 'totals' table with the value of Inserts
229 */
230 }).then((int iReturnVal) {
231 int iInsertTot = iReturnVal;
232 sCheckpoint = "fUpdateTotalsTable (insert value)";
233 fUpdateTotalsTable().then((_) {
234 return iInsertTot;
235 });
236 /*
237 * Display totals for inserts
238 */
239 }).then((int iInsertTot) {
240 ogTotals.fPrintTotals(
241 "${iInsertTot} rows inserted - Inserts completed",
242 iInsertTot, oStopwatch.elapsedMilliseconds);
243
244 return null;
245 /*
192 /*
193 * Clear main table if selected
194 */
195 }).then((tReturnVal) {
196 if (tReturnVal)
197 ogPrintLine.fPrintForce("Random Keys Cleared");
198 sCheckpoint = "Clear Table ${S_TABLE_NAME}";
199 bool tClearTable = (lsInput[I_CLEAR_YN] == "y");
200 if (!tFirstInstance)
201 return null;
202 return fClearTable(tClearTable, S_TABLE_NAME);
203
204 /*
205 * Update control row to increment count of instances started
206 */
207 }).then((_) {
1073 /*
1074 * Update totals table with values from inserts and updates
1075 */
1076 async.Future<bool> fUpdateTotalsTable() {
1077 async.Completer<bool> oCompleter = new async.Completer<bool>();
1078
1079 String sCcyValue = ogCcy.fCcyIntToString(ogTotals.iTotAmt);
1080
1081 print ("\n********* Total = ${sCcyValue} \n");
1082
1083 oCompleter.complete(true);
1084 return oCompleter.future;
1085 }
Your function L230-235 does not return anything and that's why your iInsertTot is null L239. To make it work you have to add a return at line 233.
231 int iInsertTot = iReturnVal;
232 sCheckpoint = "fUpdateTotalsTable (insert value)";
233 return fUpdateTotalsTable().then((_) {
234 return iInsertTot;
235 });

Resources