Skip to content

[JS] Connection error #155

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

Closed
IrishWhiskey opened this issue May 11, 2021 · 6 comments
Closed

[JS] Connection error #155

IrishWhiskey opened this issue May 11, 2021 · 6 comments
Labels
bug Something isn't working

Comments

@IrishWhiskey
Copy link
Contributor

Hi! For some reason I keep getting a connection error.

Error: Error: getaddrinfo ENOTFOUND localhost:8080
    at ClientRequest.<anonymous> (/home/user/Desktop/dtwin/twin/node_modules/@eclipse-ditto/ditto-javascript-client-node/dist/node/src/node-http.js:67:27)
    at ClientRequest.emit (node:events:365:28)
    at TLSSocket.socketErrorListener (node:_http_client:447:9)
    at TLSSocket.emit (node:events:365:28)
    at emitErrorNT (node:internal/streams/destroy:193:8)
    at emitErrorCloseNT (node:internal/streams/destroy:158:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)
error Command failed with exit code 1.

Am I doing anything wrong?

Here is the code:

import {                                                                                                                                                                                                   
    DittoNodeClient,                                                                                                                                                                                       
    NodeHttpBasicAuth,                                                                                                                                                                                     
    Thing,                                                                                                                                                                                                 
} from "@eclipse-ditto/ditto-javascript-client-node";                                                                                                                                                      
                                                                                                                                                                                                           
const domain = "localhost:8080";                                                                                                                                                                           
const username = "ditto";                                                                                                                                                                                  
const password = "ditto";                                                                                                                                                                                                                                                                                                                                                             
                                                                                                                                                                                                           
const client = DittoNodeClient.newHttpClient()                                                                                                                                                             
    .withoutTls()                                                                                                                                                                                          
    .withDomain(domain)                                                                                                                                                                                    
    .withAuthProvider(NodeHttpBasicAuth.newInstance(username, password))                                                                                                                                   
    .build();                                                                                                                                                                                              
                                                                                                                                                                                                           
const thingsHandle = client.getThingsHandle();                                                                                                                                                             
                                                                                                                                                                                                           
const thing = new Thing("the:thing");                                                                                                                                                                      
thingsHandle                                                                                                                                                                                               
    .putThing(thing)                                                                                                                                                                                       
    .then((result) =>                                                                                                                                                                                      
        console.log(
            `Finished putting thing with result: ${JSON.stringify(result)}`
        )
    );

Also if I execute the following command:

curl -u devops:foobar http://localhost:8080/status/health

I get the following output

{"label":"roles","status":"UP","children":[{"label":"expected-roles","status":"UP","details":[{"INFO":{"missing-roles":[],"extra-roles":[]}}]},{"label":"concierge","status":"UP","children":[{"label":"172.20.0.5:2551","status":"UP","children":[{"label":"persistence","status":"UP"},{"label":"SingletonStatusReporter","status":"UP","details":[{"INFO":{"enabled":true,"events":[],"credit-decisions":[],"actions":[]}}]}]}]},{"label":"things","status":"UP","children":[{"label":"172.20.0.7:2551","status":"UP","children":[{"label":"persistence","status":"UP"},{"label":"MongoMetricsReporter","status":"UP","details":[{"INFO":{"reporter":"/user/thingsRoot/healthCheckingActor/MongoMetricsReporter","resolution":"PT5S","maxTimerNanos":[0,0,0,0,0]}}]}]}]},{"label":"connectivity","status":"UP","children":[{"label":"172.20.0.9:2551","status":"UP","children":[{"label":"persistence","status":"UP"}]}]},{"label":"policies","status":"UP","children":[{"label":"172.20.0.3:2551","status":"UP","children":[{"label":"persistence","status":"UP"}]}]},{"label":"things-search","status":"UP","children":[{"label":"172.20.0.6:2551","status":"UP","children":[{"label":"persistence","status":"UP"},{"label":"backgroundSync","status":"UP","details":[{"INFO":{"enabled":true,"events":[],"progressPersisted":":_","progressIndexed":":_"}}]}]}]},{"label":"gateway","status":"UP","children":[{"label":"172.20.0.8:2551","status":"UP"}]}]}
@ffendt
Copy link
Contributor

ffendt commented May 12, 2021

Hi @IrishWhiskey,
thanks for this detailed description. I was able to reproduce your problem. This seems to be caused by two different implementation faults in the client:

  1. NodeRequester uses the https module for requests, even if the client was built with withoutTls() (see https://github.com/eclipse/ditto-clients/blob/master/javascript/lib/node/src/node-http.ts#L67).
  2. NodeRequester does not split the domain into host and port, as it would be required by the https module.

If possible for you, you should be able to get around this using the WebSocket implementation until there are fixes.
E.g.

DittoNodeClient.newWebSocketClient()                                                                                                                                                             
    .withoutTls()                                                                                                                                                                                          
    .withDomain(domain)                                                                                                                                                                                    
    .withAuthProvider(NodeHttpBasicAuth.newInstance(username, password))           
    .withoutBuffer()
    .twinChannel()                                                                                                                        
    .build(); 

@IrishWhiskey
Copy link
Contributor Author

IrishWhiskey commented May 12, 2021

Hi Florian! Thanks for your response. I managed to make it work with REST. However I get another error with websocket.

node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "#<Object>".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

Here is the new code:

import {                                                                                                                                                                                                   
    DittoNodeClient,                                                                                                                                                                                       
    NodeHttpBasicAuth,                                                                                                                                                                                     
    Thing,                                                                                                                                                                                                 
} from "@eclipse-ditto/ditto-javascript-client-node";                                                                                                                                                      
                                                                                                                                                                                                           
const domain = "localhost:8080";                                                                                                                                                                           
const username = "ditto";                                                                                                                                                                                  
const password = "ditto";                                                                                                                                                                                                                                                                                                                                                                       
                                                                                                                                                                                                           
const client = DittoNodeClient.newWebSocketClient()                                                                                                                                                        
    .withoutTls()                                                                                                                                                                                          
    .withDomain(domain)                                                                                                                                                                                    
    .withAuthProvider(NodeHttpBasicAuth.newInstance(username, password))                                                                                                                                   
    .withoutBuffer()                                                                                                                                                                                       
    .twinChannel()                                                                                                                                                                                         
    .build();                                                                                                                                                                                              
                                                                                                                                                                                                           
const thingsHandle = client.getThingsHandle();                                                                                                                                                             
                                                                                                                                                                                                           
const thing = new Thing("the:thing");                                                                                                                                                                      
thingsHandle                                                                                                                                                                                               
    .putThing(thing)                                                                                                                                                                                       
    .then((result) =>                                                                                                                                                                                      
        console.log(
            `Finished putting thing with result: ${JSON.stringify(result)}`
        )
    );

@ffendt
Copy link
Contributor

ffendt commented May 12, 2021

Hi @IrishWhiskey,
yes sure, we'd be happy to have a look at a PR, if you have a fix for the REST problems 👍 .

I'll also have a look into the WebSocket problem.

@ffendt ffendt added the bug Something isn't working label May 12, 2021
@ffendt
Copy link
Contributor

ffendt commented May 26, 2021

Hi @IrishWhiskey,

on your problem with the WebSocket connection:

  • For the WebSocket client you should use NodeWebSocketBasicAuth instead of NodeHttpBasicAuth
  • The error probably comes from not providing a catch for the request you're doing. Try
thingsHandle                                                                                                                                                                                               
    .putThing(thing)                                                                                                                                                                                       
    .then((result) =>                                                                                                                                                                                      
        console.log(
            `Finished putting thing with result: ${JSON.stringify(result)}`
        )
    )
    .catch(e => console.error(`Caught exception.`,e ));
  • The root cause of the error is probably, that the WebSocket is not yet connected when firing the request (it connects asynchronously). You should be probably able to workaround this by using a buffered WebSocket connection. E.g. replace .withoutBuffer() with .withBuffer(5) in the builder. As a side note, I also noticed a flaw in the buffered implementation which I described in [JS] Buffered WebSocket client sends messages before being connected #158

@IrishWhiskey
Copy link
Contributor Author

Hi @ffendt, thanks for your help

@ffendt
Copy link
Contributor

ffendt commented Jun 1, 2021

Then I'll close this for now. You can reopen the issue if the problem remains.

@ffendt ffendt closed this as completed Jun 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants