csharp icon indicating copy to clipboard operation
csharp copied to clipboard

The given key 'key' was not present in the dictionary (at GenerateKey)

Open JCKodel opened this issue 6 years ago • 1 comments

While running this code (using the Emitter nuget on a .net core console project):

var emitter = new Emitter.Connection();

emitter.Connect();

emitter.GenerateKey("MY_SECRET_KEY_COPIED_FROM_CONSOLE", "chat/", Emitter.Messages.EmitterKeyType.ReadWrite, (r) =>
{
        // This never runs
	Console.WriteLine(r.Status + ": " + r.Key);
});

this error is thrown:

Error: System.Collections.Generic.KeyNotFoundException: The given key 'key' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Emitter.Messages.KeygenResponse.FromJson(String json) in C:\projects\csharp-133tg\Emitter\Messages\KeygenResponse.cs:line 50
   at Emitter.Connection.OnMessageReceived(Object sender, MqttMsgPublishEventArgs e) in C:\projects\csharp-133tg\Emitter\Emitter.cs:line 427

JCKodel avatar Feb 28 '19 16:02 JCKodel

Using the latest source code, the error remains. Debugging shows that Emitter responds to the keygen request this json:

{"status":401,"message":"the security key provided is not authorized to perform this operation"}

At KeygenResponse.cs, line 47, there is no error handling code written (it assumes the response will always have a "key" key, hence the exception):

public static KeygenResponse FromJson(string json)
{
        var map = JsonSerializer.DeserializeString(json) as Hashtable;
        var response = new KeygenResponse();

        response.Key = (string)map["key"];
        response.Channel = (string)map["channel"];
        response.Status = Convert.ToInt32(map["status"].ToString());
            
        return response;
}

The safest code would be:

public static KeygenResponse FromJson(string json)
{
        var map = JsonSerializer.DeserializeString(json) as Hashtable;
	var response = new KeygenResponse();
	object key;
	object channel;
	object message;
	object status;

	map.TryGetValue("key", out key);
	map.TryGetValue("channel", out channel);
	map.TryGetValue("message", out message);
	map.TryGetValue("status", out status);

	if(key != null) response.Key = (string)key;
	if(channel != null) response.Channel = (string)channel;
	if(status != null) response.Status = Convert.ToInt32(status);

	if(response.Status > 299 && message != null)
	{
		throw new EmitterException((EmitterEventCode)response.Status, (string)message);
	}
            
    return response;
}

That would give me a more meaningful error message (although is my first try with Emitter, I have no clue what is going on):

Error: Emitter.EmitterException: the security key provided is not authorized to perform this operation
   at Emitter.Messages.KeygenResponse.FromJson(String json) in C:\Temp\csharp-master\Emitter\Messages\KeygenResponse.cs:line 70
   at Emitter.Messages.KeygenResponse.FromBinary(Byte[] message) in C:\Temp\csharp-master\Emitter\Messages\KeygenResponse.cs:line 80
   at Emitter.Connection.OnMessageReceived(Object sender, MqttMsgPublishEventArgs e) in C:\Temp\csharp-master\Emitter\Emitter.cs:line 430

JCKodel avatar Feb 28 '19 17:02 JCKodel