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

Stop subscribe mailbox with unknown error #174

Closed
duongkha opened this issue Mar 28, 2017 · 30 comments
Closed

Stop subscribe mailbox with unknown error #174

duongkha opened this issue Mar 28, 2017 · 30 comments
Assignees
Labels
Milestone

Comments

@duongkha
Copy link

Hi,

I am trying to subscribe a mailbox to get new email coming and the application is running continuously to monitor the new email automatically. I use SubscribeToStreamingNotificationsOnAllFolders and StreamingSubscriptionConnection with timeout 30 minutes.

I also subscribe OnDisconnect event to reconnect by calling connection.Open();
and OnNotificationEvent to listen new email.

It was working very well for monitoring the new email in mailbox, however, it is stopped after running for a while (a day or some hours) without error alarm. I don't know when i will happen, just see it stops listen the new email. I have no idea if this is an issue of library or we need to do something extra to handle the case to re-connect to mailbox.

Could you please advise what i can do to fix the issue?

Thanks in advanced.

@gautamsi
Copy link
Owner

are you catching error on connection.Open() promise?

@duongkha
Copy link
Author

No, i am not. I should catch error and call Open again,right?

@gautamsi
Copy link
Owner

first check what is the error it give, log it in console or in file to review later. if there is something I can fix that would help others

@soptimizer
Copy link

soptimizer commented Mar 29, 2017

Hi, i have similar problem. When internet connection lost, i catch disconnect event. And i try reopen connection but i can not catch any error.

    conn.Open().then((err) => {
            console.log("error: " + err);
        });

Is this code true?

@gautamsi
Copy link
Owner

@soptimizer you can not do it this way, .then(success function, error function) is the syntax. You have to use 2nd parameter for exception in .then

if you are consuming ews-javascript-api@next then you can also use BlueBird's .catch.

@soptimizer
Copy link

soptimizer commented Mar 30, 2017

@gautamsi thanks for fast response.
I tried code at the below, but not work for me.

    conn.OnDisconnect.push(() => {
        console.log("OnDisconnect : " + new Date() ); // is working
        conn.Open().then( function(success) {
                            console.log("OK : " + success)  // not working
                         },
                         function(error) {
                            console.log("ERR : " + error) // not working
                         },
                        );
        console.log("test text");  // not working
    });

In this code, conn.Open() is working. But after the ".then" function is not working.
I do not see any "success" message, neither "error" message nor "test text" message.

@duongkha
Copy link
Author

this is what i do and works for me.
$q(connection.Open())
.then(function(success){
console.log("ews connected.");
},
function(error){
console.log("ews connection error.");
console.log(error);
});

@gautamsi
Copy link
Owner

@duongkha did you receive any error in the error block?

@duongkha
Copy link
Author

Yes. the error is "'You must add at least one subscription to this connection before it can be opened.'"

I guess that it happened inside your code that the subscription somehow is disappeared.
It is not happening often, but it can happen at any time, some hours or a day since my app is always running to listen new email.

@soptimizer
Copy link

I tried q promise and it works. Success function was called. But when i lost the internet connection, error function was not called. So i can not handle net connection error.

Do you have a suggestion for me?

@gautamsi
Copy link
Owner

I will take a look on this sometime this week.

@duongkha
Copy link
Author

what i am trying to do is dispose the current connection and create new connection with subscription, it seems to be working now. but let's see if it is stopped working for long run or not.

@soptimizer
Copy link

soptimizer commented Mar 30, 2017

@duongkha How do you catch "disconnection"? In my code when i disconnect the connection, "OnDisconnect" is working correctly. In this situation, I call conn.Open() but I can not receive any error.

@duongkha
Copy link
Author

duongkha commented Apr 5, 2017

i also subscribe Disconnected event and reconnect again only.

@duongkha
Copy link
Author

duongkha commented Apr 5, 2017

@gautamsi : I tried to set the timeout to 1 minutes of subscribing the mailbox. however, i recognized that sometimes, it called to reopen the connection and it failed, nothing response with Open() call. What should we do when the Open is failed? Should we recall Open again?

@soptimizer
Copy link

soptimizer commented Apr 5, 2017

@duongkha I'm struggling with the same problem. How can i catch when the Open function is failed?

Not : Why are conn.IsOpen and conn.isDisposed always false?

@gautamsi
Additional Info : I tried ews-javascript-api@next. When i call conn.Open() without internet connection, i get an error message like at the bottom. But i cannot handle or catch, it just show error message.

Unhandled rejection Error: read ECONNRESET
    at exports._errnoException (util.js:1022:11)
    at TLSWrap.onread (net.js:569:26)

Unhandled rejection TypeError: resperr.getAllResponseHeaders is not a function
    at D:\ews-rest-api\node_modules\ews-javascript-api\js\Core\Requests\HangingServiceRequestBase.js:125:121
    at tryCatcher (D:\ews-rest-api\node_modules\bluebird\js\release\util.js:16:23)
    at Promise._settlePromiseFromHandler (D:\ews-rest-api\node_modules\bluebird\js\release\promise.js:512:31)
    at Promise._settlePromise (D:\ews-rest-api\node_modules\bluebird\js\release\promise.js:569:18)
    at Promise._settlePromise0 (D:\ews-rest-api\node_modules\bluebird\js\release\promise.js:614:10)
    at Promise._settlePromises (D:\ews-rest-api\node_modules\bluebird\js\release\promise.js:689:18)
    at Async._drainQueue (D:\ews-rest-api\node_modules\bluebird\js\release\async.js:133:16)
    at Async._drainQueues (D:\ews-rest-api\node_modules\bluebird\js\release\async.js:143:10)
    at Immediate.Async.drainQueues (D:\ews-rest-api\node_modules\bluebird\js\release\async.js:17:14)
    at runCallback (timers.js:649:20)
    at tryOnImmediate (timers.js:622:5)
    at processImmediate [as _immediateCallback] (timers.js:594:5)

Unhandled rejection Error: getaddrinfo ENOTFOUND outlook.office365.com outlook.office365.com:443
    at errnoException (dns.js:28:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)

Unhandled rejection TypeError: resperr.getAllResponseHeaders is not a function
    at D:\ews-rest-api\node_modules\ews-javascript-api\js\Core\Requests\HangingServiceRequestBase.js:125:121
    at tryCatcher (D:\ews-rest-api\node_modules\bluebird\js\release\util.js:16:23)
    at Promise._settlePromiseFromHandler (D:\ews-rest-api\node_modules\bluebird\js\release\promise.js:512:31)
    at Promise._settlePromise (D:\ews-rest-api\node_modules\bluebird\js\release\promise.js:569:18)
    at Promise._settlePromise0 (D:\ews-rest-api\node_modules\bluebird\js\release\promise.js:614:10)
    at Promise._settlePromises (D:\ews-rest-api\node_modules\bluebird\js\release\promise.js:689:18)
    at Async._drainQueue (D:\ews-rest-api\node_modules\bluebird\js\release\async.js:133:16)
    at Async._drainQueues (D:\ews-rest-api\node_modules\bluebird\js\release\async.js:143:10)
    at Immediate.Async.drainQueues (D:\ews-rest-api\node_modules\bluebird\js\release\async.js:17:14)
    at runCallback (timers.js:649:20)
    at tryOnImmediate (timers.js:622:5)
    at processImmediate [as _immediateCallback] (timers.js:594:5)

@gautamsi gautamsi self-assigned this Apr 6, 2017
@gautamsi gautamsi added the bug label Apr 6, 2017
@gautamsi gautamsi added this to the 0.9.0 milestone Apr 6, 2017
@gautamsi
Copy link
Owner

gautamsi commented Apr 6, 2017

isDisposed is a private member. you should not need access.
isConnected is never set to true which is a bug.

try the gist for subscription example. It worked for me when there was no internet.

@soptimizer
Copy link

@gautamsi I tried code that you suggested. It is working for when connection cut off. But Promise not work for Open() function. I can not understand Open() process successed or failed.

If i solve this problem i can handle all condition that i need.

Do you have a suggestion for me?

@gautamsi
Copy link
Owner

gautamsi commented Apr 6, 2017

I see the problem. the issue is connection.open() does not return promise, but internally it tries to reject the promise, looks like it has to be changed to throw because I do not want this to block any code (async scenario).

Will have to take deeper look on this.

@duongkha
Copy link
Author

@gautamsi Yea. I see this problem too. I can't handle when the internet is interrupted. The Open() function does not return success or fail. Do you have idea to check if the connection state is failed? I need to repeatedly reconnect in my code.

gautamsi added a commit that referenced this issue Apr 13, 2017
@gautamsi
Copy link
Owner

you can now use connection.Open().then(successFunc,errFunc). use ews-javascript-api@next meanwhile.

@soptimizer
Copy link

soptimizer commented Apr 14, 2017

Hi, gautam.

I tested this with 0.9.0-dev.5.

I encountered a strange error. When i call open function first with then(successFunc,errFunc) the code do not enter to success or error func. When connection timeout, previous success message shown. Sample code and output at below.

            console.log("Precalling... " + counter );
            connection.Open().then(
                function(success){
                    console.log("OK" + counter  );
                    counter++;
                },
                function(error){
                    console.log("FAIL" + counter  );
                    counter++;
                });

Precalling. 1
(Timeout - Try Reopen) Fri Apr 14 2017 13:10:12 // This output must be there below (After the Ok. 1 message)
Ok. 1
Precalling. 2
(Timeout - Try Reopen) Fri Apr 14 2017 13:11:14 // This output must be there below (After the Ok. 2 message)
Ok. 2
...

@gautamsi
Copy link
Owner

I see the way current code is organized, It resolves only after HTTP connection stream is disconnected. I can resolve the promise early in header event (when first headers arrive) but that may be bit early. other place I can resolve promise is when first data section arrives, but that may be late, data event is fired when first set of notification is received.

@gautamsi gautamsi reopened this Apr 14, 2017
@gautamsi
Copy link
Owner

I have finally decided to wrap this in OnResponseHeader delegate (similar to OnDisconnect) so that you can also look for headers and test for connection (which is always true if you received header).

@duongkha
Copy link
Author

@gautamsi : My app is running 24/7, but if there is any error with the connection open sometimes, there is no returned error that helps me to know in order to call reconnect. My question is " Is it possible to check the connection state by a timer to know if the connection is still ok"?

gautamsi added a commit that referenced this issue May 19, 2017
@gautamsi
Copy link
Owner

this is published in dev6 tonight.
there is still a caveat, the promise will never resolve as this is streaming. you can first detect connection by subscribing to OnResponseHeader delegate use connection.OnResponseHeader.push(function(headers){/* do something with headers*/}); This actually gives you header information. I am not checking if the header is for success or failure. on failures, it will not have data stream and it will change IsOpen from true to false immediately.

you can use timer to check connection.IsOpen value, which will be true if the connection is still open. let me know what you find.

@gautamsi
Copy link
Owner

please reopen if needed.

@hgezim
Copy link

hgezim commented Jan 19, 2018

@gautamsi, thanks for this awesome library!

I'm also experincing the issue with .Open() not indicating success or failure. I even used the q library as described above to no avail:

    private onDisconnect(args: ews.SubscriptionErrorEventArgs) {
        winston.error('[exchange] subscription disconnected:', args.Exception);
        winston.error('[exchange] subscription number before reconnecting:', this.connection.CurrentSubscriptions.length);
        q(this.connection.Open())
.then(function(success){
console.log("ews connected.");
},
function(error){
console.log("ews connection error.");
console.log(error);
});

Output:

error: [exchange] subscription disconnected:
error: [exchange] subscription number before reconnecting: 1
error: [exchange] subscription number after reconnecting: 1

The bigger issue is that for some reason, we stop receiving email notifications.

@hgezim
Copy link

hgezim commented Jan 19, 2018

Furthermore, connection.IsOpen always seems to return true, even when I disconnect my internet:

        setInterval(() => {
            console.log('conn is open?: ', this.connection.IsOpen);
        }, 5000);

@gautamsi
Copy link
Owner

I have to find time to replicate this. stay tuned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants