Repository: microsoft/ApplicationInsights-node.js (ts)

Issue:
TrackDependency update is breaking the code.
After updating the applicationinsights dependency version to 1.7.2, the **track dependency** code is breaking. It is working fine with 1.4.2 version..

I have found that, the **telemetry name** is optional, and previously we were just logging it without caring about it length and all.. But in the updated version(1.7.2), we are trying to find the "length" property of the name, and if it is undefined, it is breaking the code.


**Stack Trace:**

**"TypeError: Cannot read property 'length' of undefined**
    at Function.EnvelopeFactory.createDependencyData (C:\test\node_modules\applicationinsights\out\Library\EnvelopeFactory.js:100:48)
    at Function.EnvelopeFactory.createEnvelope (C:\test\node_modules\applicationinsights\out\Library\EnvelopeFactory.js:26:40)
    at NodeClient.TelemetryClient.track (C:\test\node_modules\applicationinsights\out\Library\TelemetryClient.js:109:44)
    at NodeClient.TelemetryClient.trackDependency (C:\test\node_modules\applicationinsights\out\Library\TelemetryClient.js:93:14)


**Code sample (Old version 1.4.2) working one**
**Breaking file path** : node_modules\applicationinsights\out\Library\EnvelopeFactory.js
**Line no:** 97

EnvelopeFactory.createDependencyData = function (telemetry) {
        var remoteDependency = new Contracts.RemoteDependencyData();
        **remoteDependency.name = telemetry.name;**
        remoteDependency.data = telemetry.data;
        remoteDependency.target = telemetry.target;
        remoteDependency.duration = Util.msToTimeSpan(telemetry.duration);
        remoteDependency.success = telemetry.success;
        remoteDependency.type = telemetry.dependencyTypeName;
        remoteDependency.properties = telemetry.properties;
        remoteDependency.resultCode = (telemetry.resultCode ? telemetry.resultCode + '' : '');
        if (telemetry.id) {
            remoteDependency.id = telemetry.id;
        }
        else {
            remoteDependency.id = Util.w3cTraceId();
        }
        var data = new Contracts.Data();
        data.baseType = Contracts.telemetryTypeToBaseType(Contracts.TelemetryType.Dependency);
        data.baseData = remoteDependency;
        return data;
    };


**Code sample (updated version 1.7.2) breaking one**
**Breaking file path** : node_modules\applicationinsights\out\Library\EnvelopeFactory.js
**Line no:** 100

`
EnvelopeFactory.createDependencyData = function (telemetry) {
        var remoteDependency = new Contracts.RemoteDependencyData();
        **remoteDependency.name = telemetry.name.length > 1024 ? telemetry.name.slice(0, 1021) + '...' : telemetry.name;**
        remoteDependency.data = telemetry.data;
        remoteDependency.target = telemetry.target;
        remoteDependency.duration = Util.msToTimeSpan(telemetry.duration);
        remoteDependency.success = telemetry.success;
        remoteDependency.type = telemetry.dependencyTypeName;
        remoteDependency.properties = telemetry.properties;
        remoteDependency.resultCode = (telemetry.resultCode ? telemetry.resultCode + '' : '');
        if (telemetry.id) {
            remoteDependency.id = telemetry.id;
        }
        else {
            remoteDependency.id = Util.w3cTraceId();
        }
        var data = new Contracts.Data();
        data.baseType = Contracts.telemetryTypeToBaseType(Contracts.TelemetryType.Dependency);
        data.baseData = remoteDependency;
        return data;
    };

`

**How to do a quick fix**: Please check whether the value is undefined/null before doing any operation(length/slice) on it.




Pull request:
fix: dependency name could be null
Fixes #594 

Patch:
diff --git a/Library/EnvelopeFactory.ts b/Library/EnvelopeFactory.ts
index 224fd62..3ee5924 100644
--- a/Library/EnvelopeFactory.ts
+++ b/Library/EnvelopeFactory.ts
@@ -115,7 +115,9 @@ class EnvelopeFactory {
 
     private static createDependencyData(telemetry: Contracts.DependencyTelemetry & Contracts.Identified): Contracts.Data<Contracts.RemoteDependencyData> {
         var remoteDependency = new Contracts.RemoteDependencyData();
-        remoteDependency.name = telemetry.name.length > 1024 ? telemetry.name.slice(0, 1021) + '...' : telemetry.name;
+        if (typeof telemetry.name === "string") {
+            remoteDependency.name = telemetry.name.length > 1024 ? telemetry.name.slice(0, 1021) + '...' : telemetry.name;
+        }
         remoteDependency.data = telemetry.data;
         remoteDependency.target = telemetry.target;
         remoteDependency.duration = Util.msToTimeSpan(telemetry.duration);
@@ -223,7 +225,7 @@ class EnvelopeFactory {
         telemetry: Contracts.AvailabilityTelemetry & Contracts.Identified,
     ): Contracts.Data<Contracts.AvailabilityData> {
         let availabilityData = new Contracts.AvailabilityData();
-        
+
         if (telemetry.id) {
             availabilityData.id = telemetry.id;
         } else {


Test patch:
diff --git a/Tests/Library/EnvelopeFactoryTests.ts b/Tests/Library/EnvelopeFactoryTests.ts
index 865323c..b31ac5a 100644
--- a/Tests/Library/EnvelopeFactoryTests.ts
+++ b/Tests/Library/EnvelopeFactoryTests.ts
@@ -8,7 +8,7 @@ import Client = require("../../Library/TelemetryClient");
 import Util = require("../../Library/Util");
 
 describe("Library/EnvelopeFactory", () => {
-        
+
     var properties: { [key: string]: string; } = { p1: "p1", p2: "p2", common: "commonArg" };
     var mockData = <any>{ baseData: { properties: {} }, baseType: "BaseTestData" };
     describe("#createEnvelope()", () => {
@@ -39,7 +39,7 @@ describe("Library/EnvelopeFactory", () => {
         });
 
         it("should allow tags to be overwritten", () => {
-          
+
             var client = new Client("key");
             var env = EnvelopeFactory.createEnvelope(<Contracts.EventTelemetry>{name:"name"}, Contracts.TelemetryType.Event, commonproperties, client.context, client.config);
             assert.deepEqual(env.tags, client.context.tags, "tags are set by default");
@@ -58,6 +58,22 @@ describe("Library/EnvelopeFactory", () => {
             assert.equal(envelope.name, "Microsoft.ApplicationInsights.key.Event");
         });
     });
+
+    describe("#createDependencyData()", () => {
+        it("should accept a telemetry item without a name", () => {
+            assert.doesNotThrow(() => {
+                var envelope = EnvelopeFactory.createEnvelope(<Contracts.DependencyTelemetry>{
+                    name: null,
+                    data: "GET https://example.com",
+                    duration: 123,
+                    success: true,
+                    resultCode: 200
+                }, Contracts.TelemetryType.Dependency);
+                assert.equal((envelope.data as Contracts.Data<Contracts.RemoteDependencyData>).baseData.name, undefined);
+            });
+        });
+    });
+
     describe("#createExceptionData()", () => {
         var simpleError: Error;
 
@@ -141,9 +157,9 @@ describe("Library/EnvelopeFactory", () => {
         it("creates data with given content", () => {
             var envelope = EnvelopeFactory.createEnvelope(availabilityTelemetry, Contracts.TelemetryType.Availability);
             var data =  <Contracts.Data<Contracts.AvailabilityData>>envelope.data;
-            
+
             assert.deepEqual(data.baseType, "AvailabilityData");
-            
+
             assert.deepEqual(data.baseData.id, availabilityTelemetry.id);
             assert.deepEqual(data.baseData.measurements, availabilityTelemetry.measurements);
             assert.deepEqual(data.baseData.success, availabilityTelemetry.success);