The November 2009 CTP of the Access Control Service brought many new changes. As you learn about these changes, you'll undoubtedly run into some hurdles. One likely hurdle is deciphering the error messages you get from the token and management services. Here's a TokenServiceException class that converts a WebException into something that's a bit easier to swallow.

   1:  public class TokenServiceException : Exception
   2:  {
   3:      public HttpStatusCode StatusCode { get; private set; }
   4:      public int SubCode { get; private set; }
   5:   
   6:      public TokenServiceException(HttpStatusCode statusCode)
   7:          // use the HTTP status code text as the message
   8:          : this(statusCode, -1, statusCode.ToString())
   9:      {
  10:      }
  11:   
  12:      public TokenServiceException(HttpStatusCode statusCode, int subCode, string message)
  13:          : base(message)
  14:      {
  15:          this.StatusCode = statusCode;
  16:          this.SubCode = subCode;
  17:      }
  18:   
  19:      public static void Throw(WebException exception)
  20:      {
  21:          HttpWebResponse response = (HttpWebResponse)exception.Response;
  22:          string body;
  23:   
  24:          using (StreamReader reader = new StreamReader(response.GetResponseStream()))
  25:          {
  26:              body = reader.ReadToEnd();
  27:          }
  28:   
  29:          // e.g., Error:Code:400:SubCode:T1000:Detail:The service namespace 'x.y' is invalid
  30:          string[] bodyParts = body.Split(new char[] { ':' }, 7);
  31:   
  32:          if (bodyParts.Length != 7 || bodyParts[0] != "Error")
  33:          {
  34:              // the body does not contain error detail information
  35:              throw new TokenServiceException(response.StatusCode);
  36:          }
  37:   
  38:          HttpStatusCode statusCode = (HttpStatusCode)int.Parse(bodyParts[2]);
  39:          int subCode = int.Parse(bodyParts[4].Substring(1));
  40:          string message = bodyParts[6];
  41:   
  42:          throw new TokenServiceException(statusCode, subCode, message);
  43:      }
  44:  }

Catch a WebException from the token service and pass it into the TokenServiceException.Throw method. Lines 29-42 of this class do the heavy lifting. They take the body of the exception and parse it into the parts that matter most to you: the HTTP status code, the machine-readable sub-code, and the error detail!

Rarely, the error response you get back from the service will contain no body. This typically indicates you've done something seriously wrong like performing an HTTP PUT on the token service endpoint instead of an HTTP POST. Fortunately, the HTTP status codes usually give you enough information to figure out what you did wrong, e.g., MethodNotAllowed.

I hope this little code snippet makes adjusting to the new changes a little easier.