diff --git a/src/Spring.Social.Dropbox/Social/Dropbox/Api/DropboxApiError.cs b/src/Spring.Social.Dropbox/Social/Dropbox/Api/DropboxApiError.cs new file mode 100644 index 0000000..a74e902 --- /dev/null +++ b/src/Spring.Social.Dropbox/Social/Dropbox/Api/DropboxApiError.cs @@ -0,0 +1,92 @@ +#region License + +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; + +namespace Spring.Social.Dropbox.Api +{ + /// + /// The enumeration is used by the class + /// to indicate what kind of error caused the exception. + /// + /// Bruno Baia + public enum DropboxApiError + { + /// + /// Unknown. + /// + Unknown, + + /// + /// Bad request parameter. + /// + BadParameter, + + /// + /// Bad or expired OAuth token. + /// + NotAuthorized, + + /// + /// Invalid operation attempted. + /// + OperationNotPermitted, + + /// + /// File or folder path not found. + /// + PathNotFound, + + /// + /// Too many metadata entries to return. + /// + TooManyEntries, + + /// + /// Chunked encoding not supported. + /// + ChunkedEncodingNotSupported, + + /// + /// Thumbnail cannot be created for the input file. + /// + ThumbnailNotSupported, + + /// + /// Internal server error. + /// + Server, + + /// + /// Server is down or is being upgraded. + /// + ServerDown, + + /// + /// Server is overloaded with request or the rate limit has been exceeded. + /// + ServerOverloadedOrRateLimitExceeded, + + /// + /// User is over quota. + /// + StorageQuotaExceeded + } +} diff --git a/src/Spring.Social.Dropbox/Social/Dropbox/Api/DropboxApiException.cs b/src/Spring.Social.Dropbox/Social/Dropbox/Api/DropboxApiException.cs new file mode 100644 index 0000000..7a28603 --- /dev/null +++ b/src/Spring.Social.Dropbox/Social/Dropbox/Api/DropboxApiException.cs @@ -0,0 +1,112 @@ +#region License + +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; + +namespace Spring.Social.Dropbox.Api +{ + /// + /// The exception that is thrown when a error occurs while consuming Dropbox REST API. + /// + /// Bruno Baia +#if !SILVERLIGHT + [Serializable] +#endif + public class DropboxApiException : SocialException + { + private DropboxApiError error; + + /// + /// Gets the Dropbox error. + /// + public DropboxApiError Error + { + get { return this.error; } + } + + /// + /// Creates a new instance of the class. + /// + /// A message about the exception. + /// The Dropbox error. + public DropboxApiException(string message, DropboxApiError error) + : base(message) + { + this.error = error; + } + + /// + /// Creates a new instance of the class. + /// + /// A message about the exception. + /// The inner exception that is the cause of the current exception. + public DropboxApiException(string message, Exception innerException) + : base(message, innerException) + { + this.error = DropboxApiError.Unknown; + } + +#if !SILVERLIGHT && !CF_3_5 + /// + /// Creates a new instance of the class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected DropboxApiException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + if (info != null) + { + this.error = (DropboxApiError)info.GetValue("Error", typeof(DropboxApiError)); + } + } + + /// + /// Populates the with + /// information about the exception. + /// + /// + /// The that holds + /// the serialized object data about the exception being thrown. + /// + /// + /// The that contains contextual + /// information about the source or destination. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + if (info != null) + { + info.AddValue("Error", this.error); + } + } +#endif + } +} diff --git a/src/Spring.Social.Dropbox/Social/Dropbox/Api/IDropbox.cs b/src/Spring.Social.Dropbox/Social/Dropbox/Api/IDropbox.cs index 7535a0c..bf351b9 100644 --- a/src/Spring.Social.Dropbox/Social/Dropbox/Api/IDropbox.cs +++ b/src/Spring.Social.Dropbox/Social/Dropbox/Api/IDropbox.cs @@ -49,7 +49,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a object representing the user's profile. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task GetUserProfileAsync(); /// @@ -60,7 +60,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a metadata for the new folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task CreateFolderAsync(string path); /// @@ -71,7 +71,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a metadata for the deleted file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task DeleteAsync(string path); /// @@ -83,7 +83,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a metadata for the moved file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task MoveAsync(string fromPath, string toPath); /// @@ -95,7 +95,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a metadata for the moved file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task CopyAsync(string fromPath, string toPath); /// @@ -111,7 +111,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a metadata for the uploaded file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task UploadFileAsync(IResource file, string path, CancellationToken cancellationToken); /// @@ -136,7 +136,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a metadata for the uploaded file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task UploadFileAsync(IResource file, string path, bool overwrite, string revision, CancellationToken cancellationToken); /// @@ -148,7 +148,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// an array of bytes containing the file's content. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task DownloadFileAsync(string path, CancellationToken cancellationToken); /// @@ -161,7 +161,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// an array of bytes containing the file's content. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task DownloadFileAsync(string path, string revision, CancellationToken cancellationToken); /// @@ -172,7 +172,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a metadata for the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task GetMetadataAsync(string path); /// @@ -185,7 +185,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a metadata for the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task GetMetadataAsync(string path, MetadataParameters parameters); /// @@ -196,7 +196,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a list of metadata entries. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task> GetRevisionsAsync(string path); /// @@ -210,7 +210,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a list of metadata entries. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task> GetRevisionsAsync(string path, int revLimit); /// @@ -222,7 +222,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a metadata for the restored file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task RestoreAsync(string path, string revision); /// @@ -234,7 +234,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a list of metadata entries for any matching files and folders. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task> SearchAsync(string path, string query); /// @@ -252,7 +252,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a list of metadata entries for any matching files and folders. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task> SearchAsync(string path, string query, int fileLimit, bool includeDeleted); /// @@ -265,7 +265,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a shareable link to the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task GetShareableLinkAsync(string path); /// @@ -278,7 +278,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// a direct link to the media file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task GetMediaLinkAsync(string path); /// @@ -293,7 +293,7 @@ public interface IDropbox : IApiBinding /// A Task that represents the asynchronous operation that can return /// an array of bytes containing the thumbnail's content. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Task DownloadThumbnailAsync(string path, ThumbnailFormat format, ThumbnailSize size); #else #if !SILVERLIGHT @@ -301,7 +301,7 @@ public interface IDropbox : IApiBinding /// Retrieves the authenticated user's Dropbox profile details. /// /// A object representing the user's profile. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. DropboxProfile GetUserProfile(); /// @@ -311,7 +311,7 @@ public interface IDropbox : IApiBinding /// /// A metadata for the new folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Entry CreateFolder(string path); /// @@ -321,7 +321,7 @@ public interface IDropbox : IApiBinding /// /// A metadata for the deleted file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Entry Delete(string path); /// @@ -332,7 +332,7 @@ public interface IDropbox : IApiBinding /// /// A metadata for the moved file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Entry Move(string fromPath, string toPath); /// @@ -343,7 +343,7 @@ public interface IDropbox : IApiBinding /// /// A metadata for the moved file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Entry Copy(string fromPath, string toPath); /// @@ -355,7 +355,7 @@ public interface IDropbox : IApiBinding /// This parameter should not point to a folder. /// /// A metadata for the uploaded file. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Entry UploadFile(IResource file, string path); /// @@ -376,7 +376,7 @@ public interface IDropbox : IApiBinding /// If matches the latest version of the file on the user's Dropbox, that file will be replaced. /// /// A metadata for the uploaded file. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Entry UploadFile(IResource file, string path, bool overwrite, string revision); /// @@ -384,7 +384,7 @@ public interface IDropbox : IApiBinding /// /// The Dropbox path to the file you want to retrieve, relative to root. /// An array of bytes containing the file's content. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. byte[] DownloadFile(string path); /// @@ -393,7 +393,7 @@ public interface IDropbox : IApiBinding /// The Dropbox path to the file you want to retrieve, relative to root. /// The revision of the file to retrieve. /// An array of bytes containing the file's content. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. byte[] DownloadFile(string path, string revision); /// @@ -403,7 +403,7 @@ public interface IDropbox : IApiBinding /// /// A metadata for the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Entry GetMetadata(string path); /// @@ -415,7 +415,7 @@ public interface IDropbox : IApiBinding /// /// A metadata for the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Entry GetMetadata(string path, MetadataParameters parameters); /// @@ -425,7 +425,7 @@ public interface IDropbox : IApiBinding /// /// A list of metadata entries. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. IList GetRevisions(string path); /// @@ -438,7 +438,7 @@ public interface IDropbox : IApiBinding /// /// A list of metadata entries. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. IList GetRevisions(string path, int revLimit); /// @@ -449,7 +449,7 @@ public interface IDropbox : IApiBinding /// /// A metadata for the restored file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. Entry Restore(string path, string revision); /// @@ -460,7 +460,7 @@ public interface IDropbox : IApiBinding /// /// A list of metadata entries for any matching files and folders. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. IList Search(string path, string query); /// @@ -477,7 +477,7 @@ public interface IDropbox : IApiBinding /// /// A list of metadata entries for any matching files and folders. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. IList Search(string path, string query, int fileLimit, bool includeDeleted); /// @@ -489,7 +489,7 @@ public interface IDropbox : IApiBinding /// /// A shareable link to the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. DropboxLink GetShareableLink(string path); /// @@ -501,7 +501,7 @@ public interface IDropbox : IApiBinding /// /// A direct link to the media file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. DropboxLink GetMediaLink(string path); /// @@ -515,7 +515,7 @@ public interface IDropbox : IApiBinding /// /// An array of bytes containing the thumbnail's content. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. byte[] DownloadThumbnail(string path, ThumbnailFormat format, ThumbnailSize size); #endif @@ -529,7 +529,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler GetUserProfileAsync(Action> operationCompleted); /// @@ -543,7 +543,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler CreateFolderAsync(string path, Action> operationCompleted); /// @@ -557,7 +557,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler DeleteAsync(string path, Action> operationCompleted); /// @@ -572,7 +572,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler MoveAsync(string fromPath, string toPath, Action> operationCompleted); /// @@ -587,7 +587,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler CopyAsync(string fromPath, string toPath, Action> operationCompleted); /// @@ -605,7 +605,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler UploadFileAsync(IResource file, string path, Action> operationCompleted); /// @@ -632,7 +632,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler UploadFileAsync(IResource file, string path, bool overwrite, string revision, Action> operationCompleted); /// @@ -646,7 +646,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler DownloadFileAsync(string path, Action> operationCompleted); /// @@ -661,7 +661,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler DownloadFileAsync(string path, string revision, Action> operationCompleted); /// @@ -675,7 +675,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler GetMetadataAsync(string path, Action> operationCompleted); /// @@ -691,7 +691,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler GetMetadataAsync(string path, MetadataParameters parameters, Action> operationCompleted); /// @@ -705,7 +705,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler GetRevisionsAsync(string path, Action>> operationCompleted); /// @@ -722,7 +722,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler GetRevisionsAsync(string path, int revLimit, Action>> operationCompleted); /// @@ -737,7 +737,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler RestoreAsync(string path, string revision, Action> operationCompleted); /// @@ -752,7 +752,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler SearchAsync(string path, string query, Action>> operationCompleted); /// @@ -773,7 +773,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler SearchAsync(string path, string query, int fileLimit, bool includeDeleted, Action>> operationCompleted); /// @@ -789,7 +789,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler GetShareableLinkAsync(string path, Action> operationCompleted); /// @@ -805,7 +805,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler GetMediaLinkAsync(string path, Action> operationCompleted); /// @@ -823,7 +823,7 @@ public interface IDropbox : IApiBinding /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. RestOperationCanceler DownloadThumbnailAsync(string path, ThumbnailFormat format, ThumbnailSize size, Action> operationCompleted); #endif diff --git a/src/Spring.Social.Dropbox/Social/Dropbox/Api/Impl/DropboxErrorHandler.cs b/src/Spring.Social.Dropbox/Social/Dropbox/Api/Impl/DropboxErrorHandler.cs new file mode 100644 index 0000000..0768a76 --- /dev/null +++ b/src/Spring.Social.Dropbox/Social/Dropbox/Api/Impl/DropboxErrorHandler.cs @@ -0,0 +1,138 @@ +#region License + +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.Net; +using System.Text; + +using Spring.Json; +using Spring.Http; +using Spring.Rest.Client; +using Spring.Rest.Client.Support; + +namespace Spring.Social.Dropbox.Api.Impl +{ + /// + /// Implementation of the that handles errors from Dropbox's REST API, + /// interpreting them into appropriate exceptions. + /// + /// Bruno Baia + class DropboxErrorHandler : DefaultResponseErrorHandler + { + // Default encoding for JSON + private static readonly Encoding DEFAULT_CHARSET = new UTF8Encoding(false); // Remove byte Order Mask (BOM) + + /// + /// Handles the error in the given response. + /// This method is only called when has returned . + /// + /// + /// This implementation throws appropriate exception if the response status code + /// is a client code error (4xx) or a server code error (5xx). + /// + /// The response message with the error + public override void HandleError(HttpResponseMessage response) + { + int type = (int)response.StatusCode / 100; + if (type == 4) + { + this.HandleClientErrors(response); + } + else if (type == 5) + { + this.HandleServerErrors(response.StatusCode); + } + + // if not otherwise handled, do default handling and wrap with ApiException + try + { + base.HandleError(response); + } + catch (Exception ex) + { + throw new DropboxApiException("Error consuming Dropbox REST API.", ex); + } + } + + private void HandleClientErrors(HttpResponseMessage response) + { + JsonValue errorValue = this.ExtractErrorDetailsFromResponse(response); + if (errorValue == null) + { + return; // unexpected error body, can't be handled here + } + string errorText = errorValue.ContainsName("error") + ? errorValue.GetValue("error") + : response.StatusDescription; + + switch (response.StatusCode) + { + case HttpStatusCode.BadRequest: + throw new DropboxApiException(errorText, DropboxApiError.BadParameter); + case HttpStatusCode.Unauthorized: + throw new DropboxApiException(errorText, DropboxApiError.NotAuthorized); + case HttpStatusCode.Forbidden: + throw new DropboxApiException(errorText, DropboxApiError.OperationNotPermitted); + case HttpStatusCode.NotFound: + throw new DropboxApiException(errorText, DropboxApiError.PathNotFound); + case HttpStatusCode.NotAcceptable: + throw new DropboxApiException(errorText, DropboxApiError.TooManyEntries); + case HttpStatusCode.LengthRequired: + throw new DropboxApiException(errorText, DropboxApiError.ChunkedEncodingNotSupported); + case HttpStatusCode.UnsupportedMediaType: + throw new DropboxApiException(errorText, DropboxApiError.ThumbnailNotSupported); + } + } + + private void HandleServerErrors(HttpStatusCode statusCode) + { + if (statusCode == HttpStatusCode.BadGateway) + { + throw new DropboxApiException("Dropbox is down or is being upgraded. Try again later.", DropboxApiError.ServerDown); + } + else if (statusCode == HttpStatusCode.ServiceUnavailable) + { + throw new DropboxApiException( + "Dropbox is experiencing high load or the rate limit has been exceeded. Try again later.", + DropboxApiError.ServerOverloadedOrRateLimitExceeded); + } + else if (statusCode == (HttpStatusCode)507) + { + throw new DropboxApiException("The storage quota has been exceeded.", DropboxApiError.StorageQuotaExceeded); + } + else + { + throw new DropboxApiException( + "Something is broken at Dropbox. Please check status page at http://status.dropbox.com/.", + DropboxApiError.Server); + } + } + + private JsonValue ExtractErrorDetailsFromResponse(HttpResponseMessage response) + { + MediaType contentType = response.Headers.ContentType; + Encoding charset = (contentType != null && contentType.CharSet != null) ? contentType.CharSet : DEFAULT_CHARSET; + string errorDetails = charset.GetString(response.Body, 0, response.Body.Length); + + JsonValue result; + return JsonValue.TryParse(errorDetails, out result) ? result : null; + } + } +} \ No newline at end of file diff --git a/src/Spring.Social.Dropbox/Social/Dropbox/Api/Impl/DropboxTemplate.cs b/src/Spring.Social.Dropbox/Social/Dropbox/Api/Impl/DropboxTemplate.cs index a5239e0..3cb73ea 100644 --- a/src/Spring.Social.Dropbox/Social/Dropbox/Api/Impl/DropboxTemplate.cs +++ b/src/Spring.Social.Dropbox/Social/Dropbox/Api/Impl/DropboxTemplate.cs @@ -90,7 +90,7 @@ public AccessLevel AccessLevel /// A Task that represents the asynchronous operation that can return /// a object representing the user's profile. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task GetUserProfileAsync() { NameValueCollection parameters = new NameValueCollection(); @@ -106,7 +106,7 @@ public Task GetUserProfileAsync() /// A Task that represents the asynchronous operation that can return /// a metadata for the new folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task CreateFolderAsync(string path) { NameValueCollection request = new NameValueCollection(); @@ -124,7 +124,7 @@ public Task CreateFolderAsync(string path) /// A Task that represents the asynchronous operation that can return /// a metadata for the deleted file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task DeleteAsync(string path) { NameValueCollection request = new NameValueCollection(); @@ -143,7 +143,7 @@ public Task DeleteAsync(string path) /// A Task that represents the asynchronous operation that can return /// a metadata for the moved file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task MoveAsync(string fromPath, string toPath) { NameValueCollection request = new NameValueCollection(); @@ -163,7 +163,7 @@ public Task MoveAsync(string fromPath, string toPath) /// A Task that represents the asynchronous operation that can return /// a metadata for the moved file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task CopyAsync(string fromPath, string toPath) { NameValueCollection request = new NameValueCollection(); @@ -187,7 +187,7 @@ public Task CopyAsync(string fromPath, string toPath) /// A Task that represents the asynchronous operation that can return /// a metadata for the uploaded file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task UploadFileAsync(IResource file, string path, CancellationToken cancellationToken) { return this.UploadFileAsync(file, path, true, null, cancellationToken); @@ -215,7 +215,7 @@ public Task UploadFileAsync(IResource file, string path, CancellationToke /// A Task that represents the asynchronous operation that can return /// a metadata for the uploaded file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task UploadFileAsync(IResource file, string path, bool overwrite, string revision, CancellationToken cancellationToken) { return this.RestTemplate.ExchangeAsync( @@ -235,7 +235,7 @@ public Task UploadFileAsync(IResource file, string path, bool overwrite, /// A Task that represents the asynchronous operation that can return /// an array of bytes containing the file's content. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task DownloadFileAsync(string path, CancellationToken cancellationToken) { return this.DownloadFileAsync(path, null, cancellationToken); @@ -251,7 +251,7 @@ public Task DownloadFileAsync(string path, CancellationToken cancellatio /// A Task that represents the asynchronous operation that can return /// an array of bytes containing the file's content. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task DownloadFileAsync(string path, string revision, CancellationToken cancellationToken) { return this.RestTemplate.ExchangeAsync( @@ -270,7 +270,7 @@ public Task DownloadFileAsync(string path, string revision, Cancellation /// A Task that represents the asynchronous operation that can return /// a metadata for the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task GetMetadataAsync(string path) { return this.GetMetadataAsync(path, new MetadataParameters()); @@ -286,7 +286,7 @@ public Task GetMetadataAsync(string path) /// A Task that represents the asynchronous operation that can return /// a metadata for the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task GetMetadataAsync(string path, MetadataParameters parameters) { return this.RestTemplate.GetForObjectAsync(this.BuildMetadataUrl(path, parameters)); @@ -300,7 +300,7 @@ public Task GetMetadataAsync(string path, MetadataParameters parameters) /// A Task that represents the asynchronous operation that can return /// a list of metadata entries. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task> GetRevisionsAsync(string path) { return this.GetRevisionsAsync(path, 0); @@ -317,7 +317,7 @@ public Task> GetRevisionsAsync(string path) /// A Task that represents the asynchronous operation that can return /// a list of metadata entries. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task> GetRevisionsAsync(string path, int revLimit) { NameValueCollection parameters = new NameValueCollection(); @@ -338,7 +338,7 @@ public Task> GetRevisionsAsync(string path, int revLimit) /// A Task that represents the asynchronous operation that can return /// a metadata for the restored file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task RestoreAsync(string path, string revision) { NameValueCollection request = new NameValueCollection(); @@ -356,7 +356,7 @@ public Task RestoreAsync(string path, string revision) /// A Task that represents the asynchronous operation that can return /// a list of metadata entries for any matching files and folders. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task> SearchAsync(string path, string query) { return this.SearchAsync(path, query, 0, false); @@ -377,7 +377,7 @@ public Task> SearchAsync(string path, string query) /// A Task that represents the asynchronous operation that can return /// a list of metadata entries for any matching files and folders. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task> SearchAsync(string path, string query, int fileLimit, bool includeDeleted) { NameValueCollection request = this.BuildSearchParameters(path, query, fileLimit, includeDeleted); @@ -394,7 +394,7 @@ public Task> SearchAsync(string path, string query, int fileLimit, /// A Task that represents the asynchronous operation that can return /// a shareable link to the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task GetShareableLinkAsync(string path) { NameValueCollection request = new NameValueCollection(); @@ -412,7 +412,7 @@ public Task GetShareableLinkAsync(string path) /// A Task that represents the asynchronous operation that can return /// a direct link to the media file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task GetMediaLinkAsync(string path) { NameValueCollection request = new NameValueCollection(); @@ -432,7 +432,7 @@ public Task GetMediaLinkAsync(string path) /// A Task that represents the asynchronous operation that can return /// an array of bytes containing the thumbnail's content. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Task DownloadThumbnailAsync(string path, ThumbnailFormat format, ThumbnailSize size) { return this.RestTemplate.GetForObjectAsync(this.BuildThumbnailsUrl(path, format, size)); @@ -443,7 +443,7 @@ public Task DownloadThumbnailAsync(string path, ThumbnailFormat format, /// Retrieves the authenticated user's Dropbox profile details. /// /// A object representing the user's profile. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public DropboxProfile GetUserProfile() { NameValueCollection parameters = new NameValueCollection(); @@ -458,7 +458,7 @@ public DropboxProfile GetUserProfile() /// /// A metadata for the new folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Entry CreateFolder(string path) { NameValueCollection request = new NameValueCollection(); @@ -475,7 +475,7 @@ public Entry CreateFolder(string path) /// /// A metadata for the deleted file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Entry Delete(string path) { NameValueCollection request = new NameValueCollection(); @@ -493,7 +493,7 @@ public Entry Delete(string path) /// /// A metadata for the moved file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Entry Move(string fromPath, string toPath) { NameValueCollection request = new NameValueCollection(); @@ -512,7 +512,7 @@ public Entry Move(string fromPath, string toPath) /// /// A metadata for the moved file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Entry Copy(string fromPath, string toPath) { NameValueCollection request = new NameValueCollection(); @@ -532,7 +532,7 @@ public Entry Copy(string fromPath, string toPath) /// This parameter should not point to a folder. /// /// A metadata for the uploaded file. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Entry UploadFile(IResource file, string path) { return this.UploadFile(file, path, true, null); @@ -556,7 +556,7 @@ public Entry UploadFile(IResource file, string path) /// If matches the latest version of the file on the user's Dropbox, that file will be replaced. /// /// A metadata for the uploaded file. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Entry UploadFile(IResource file, string path, bool overwrite, string revision) { return this.RestTemplate.Exchange( @@ -568,7 +568,7 @@ public Entry UploadFile(IResource file, string path, bool overwrite, string revi /// /// The Dropbox path to the file you want to retrieve, relative to root. /// An array of bytes containing the file's content. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public byte[] DownloadFile(string path) { return this.DownloadFile(path, null); @@ -580,7 +580,7 @@ public byte[] DownloadFile(string path) /// The Dropbox path to the file you want to retrieve, relative to root. /// The revision of the file to retrieve. /// An array of bytes containing the file's content. - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public byte[] DownloadFile(string path, string revision) { return this.RestTemplate.GetForObject(this.BuildDownloadUrl(path, revision)); @@ -593,7 +593,7 @@ public byte[] DownloadFile(string path, string revision) /// /// A metadata for the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Entry GetMetadata(string path) { return this.GetMetadata(path, new MetadataParameters()); @@ -608,7 +608,7 @@ public Entry GetMetadata(string path) /// /// A metadata for the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Entry GetMetadata(string path, MetadataParameters parameters) { return this.RestTemplate.GetForObject(this.BuildMetadataUrl(path, parameters)); @@ -621,7 +621,7 @@ public Entry GetMetadata(string path, MetadataParameters parameters) /// /// A list of metadata entries. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public IList GetRevisions(string path) { return this.GetRevisions(path, 0); @@ -637,7 +637,7 @@ public IList GetRevisions(string path) /// /// A list of metadata entries. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public IList GetRevisions(string path, int revLimit) { NameValueCollection parameters = new NameValueCollection(); @@ -657,7 +657,7 @@ public IList GetRevisions(string path, int revLimit) /// /// A metadata for the restored file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public Entry Restore(string path, string revision) { NameValueCollection request = new NameValueCollection(); @@ -674,7 +674,7 @@ public Entry Restore(string path, string revision) /// /// A list of metadata entries for any matching files and folders. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public IList Search(string path, string query) { return this.Search(path, query, 0, false); @@ -694,7 +694,7 @@ public IList Search(string path, string query) /// /// A list of metadata entries for any matching files and folders. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public IList Search(string path, string query, int fileLimit, bool includeDeleted) { NameValueCollection request = this.BuildSearchParameters(path, query, fileLimit, includeDeleted); @@ -710,7 +710,7 @@ public IList Search(string path, string query, int fileLimit, bool includ /// /// A shareable link to the file or folder. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public DropboxLink GetShareableLink(string path) { NameValueCollection request = new NameValueCollection(); @@ -727,7 +727,7 @@ public DropboxLink GetShareableLink(string path) /// /// A direct link to the media file. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public DropboxLink GetMediaLink(string path) { NameValueCollection request = new NameValueCollection(); @@ -746,7 +746,7 @@ public DropboxLink GetMediaLink(string path) /// /// An array of bytes containing the thumbnail's content. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public byte[] DownloadThumbnail(string path, ThumbnailFormat format, ThumbnailSize size) { return this.RestTemplate.GetForObject(this.BuildThumbnailsUrl(path, format, size)); @@ -763,7 +763,7 @@ public byte[] DownloadThumbnail(string path, ThumbnailFormat format, ThumbnailSi /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler GetUserProfileAsync(Action> operationCompleted) { NameValueCollection parameters = new NameValueCollection(); @@ -782,7 +782,7 @@ public RestOperationCanceler GetUserProfileAsync(Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler CreateFolderAsync(string path, Action> operationCompleted) { NameValueCollection request = new NameValueCollection(); @@ -803,7 +803,7 @@ public RestOperationCanceler CreateFolderAsync(string path, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler DeleteAsync(string path, Action> operationCompleted) { NameValueCollection request = new NameValueCollection(); @@ -825,7 +825,7 @@ public RestOperationCanceler DeleteAsync(string path, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler MoveAsync(string fromPath, string toPath, Action> operationCompleted) { NameValueCollection request = new NameValueCollection(); @@ -848,7 +848,7 @@ public RestOperationCanceler MoveAsync(string fromPath, string toPath, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler CopyAsync(string fromPath, string toPath, Action> operationCompleted) { NameValueCollection request = new NameValueCollection(); @@ -874,7 +874,7 @@ public RestOperationCanceler CopyAsync(string fromPath, string toPath, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler UploadFileAsync(IResource file, string path, Action> operationCompleted) { return this.UploadFileAsync(file, path, true, null, operationCompleted); @@ -904,7 +904,7 @@ public RestOperationCanceler UploadFileAsync(IResource file, string path, Action /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler UploadFileAsync(IResource file, string path, bool overwrite, string revision, Action> operationCompleted) { return this.RestTemplate.ExchangeAsync( @@ -927,7 +927,7 @@ public RestOperationCanceler UploadFileAsync(IResource file, string path, bool o /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler DownloadFileAsync(string path, Action> operationCompleted) { return this.DownloadFileAsync(path, null, operationCompleted); @@ -945,7 +945,7 @@ public RestOperationCanceler DownloadFileAsync(string path, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler DownloadFileAsync(string path, string revision, Action> operationCompleted) { return this.RestTemplate.GetForObjectAsync(this.BuildDownloadUrl(path, revision), operationCompleted); @@ -962,7 +962,7 @@ public RestOperationCanceler DownloadFileAsync(string path, string revision, Act /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler GetMetadataAsync(string path, Action> operationCompleted) { return this.GetMetadataAsync(path, new MetadataParameters(), operationCompleted); @@ -981,7 +981,7 @@ public RestOperationCanceler GetMetadataAsync(string path, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler GetMetadataAsync(string path, MetadataParameters parameters, Action> operationCompleted) { return this.RestTemplate.GetForObjectAsync(this.BuildMetadataUrl(path, parameters), operationCompleted); @@ -998,7 +998,7 @@ public RestOperationCanceler GetMetadataAsync(string path, MetadataParameters pa /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler GetRevisionsAsync(string path, Action>> operationCompleted) { return this.GetRevisionsAsync(path, 0, operationCompleted); @@ -1018,7 +1018,7 @@ public RestOperationCanceler GetRevisionsAsync(string path, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler GetRevisionsAsync(string path, int revLimit, Action>> operationCompleted) { NameValueCollection parameters = new NameValueCollection(); @@ -1042,7 +1042,7 @@ public RestOperationCanceler GetRevisionsAsync(string path, int revLimit, Action /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler RestoreAsync(string path, string revision, Action> operationCompleted) { NameValueCollection request = new NameValueCollection(); @@ -1063,7 +1063,7 @@ public RestOperationCanceler RestoreAsync(string path, string revision, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler SearchAsync(string path, string query, Action>> operationCompleted) { return this.SearchAsync(path, query, 0, false, operationCompleted); @@ -1087,7 +1087,7 @@ public RestOperationCanceler SearchAsync(string path, string query, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler SearchAsync(string path, string query, int fileLimit, bool includeDeleted, Action>> operationCompleted) { NameValueCollection request = this.BuildSearchParameters(path, query, fileLimit, includeDeleted); @@ -1107,7 +1107,7 @@ public RestOperationCanceler SearchAsync(string path, string query, int fileLimi /// /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler GetShareableLinkAsync(string path, Action> operationCompleted) { NameValueCollection request = new NameValueCollection(); @@ -1128,7 +1128,7 @@ public RestOperationCanceler GetShareableLinkAsync(string path, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler GetMediaLinkAsync(string path, Action> operationCompleted) { NameValueCollection request = new NameValueCollection(); @@ -1151,7 +1151,7 @@ public RestOperationCanceler GetMediaLinkAsync(string path, Action /// A instance that allows to cancel the asynchronous operation. /// - /// If there is an error while communicating with Dropbox. + /// If there is an error while communicating with Dropbox. public RestOperationCanceler DownloadThumbnailAsync(string path, ThumbnailFormat format, ThumbnailSize size, Action> operationCompleted) { return this.RestTemplate.GetForObjectAsync(this.BuildThumbnailsUrl(path, format, size), operationCompleted); @@ -1183,6 +1183,7 @@ public IRestOperations RestOperations protected override void ConfigureRestTemplate(RestTemplate restTemplate) { restTemplate.BaseAddress = API_URI_BASE; + restTemplate.ErrorHandler = new DropboxErrorHandler(); } /// diff --git a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2008-NET20.csproj b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2008-NET20.csproj index e099ea3..741f4ba 100644 --- a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2008-NET20.csproj +++ b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2008-NET20.csproj @@ -54,10 +54,13 @@ + + + diff --git a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2008-NET35.csproj b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2008-NET35.csproj index 3df9fbc..93e5cb5 100644 --- a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2008-NET35.csproj +++ b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2008-NET35.csproj @@ -54,10 +54,13 @@ + + + diff --git a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-NET40.csproj b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-NET40.csproj index 4005158..fdfd2e8 100644 --- a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-NET40.csproj +++ b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-NET40.csproj @@ -111,6 +111,9 @@ + + + diff --git a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-SL40.csproj b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-SL40.csproj index f1f97d8..2ea777e 100644 --- a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-SL40.csproj +++ b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-SL40.csproj @@ -65,10 +65,13 @@ + + + diff --git a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-SL50.csproj b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-SL50.csproj index 7b4c3a8..f5dceb8 100644 --- a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-SL50.csproj +++ b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-SL50.csproj @@ -66,10 +66,13 @@ + + + diff --git a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-WP70.csproj b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-WP70.csproj index 63236cf..74d91f7 100644 --- a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-WP70.csproj +++ b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-WP70.csproj @@ -59,10 +59,13 @@ + + + diff --git a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-WP71.csproj b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-WP71.csproj index 238d57c..387f419 100644 --- a/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-WP71.csproj +++ b/src/Spring.Social.Dropbox/Spring.Social.Dropbox.2010-WP71.csproj @@ -59,10 +59,13 @@ + + + diff --git a/test/Spring.Social.Dropbox.Tests/Social/Dropbox/Api/Impl/ErrorHandlerTests.cs b/test/Spring.Social.Dropbox.Tests/Social/Dropbox/Api/Impl/ErrorHandlerTests.cs new file mode 100644 index 0000000..f9d512a --- /dev/null +++ b/test/Spring.Social.Dropbox.Tests/Social/Dropbox/Api/Impl/ErrorHandlerTests.cs @@ -0,0 +1,117 @@ +#region License + +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using System; +using System.Net; + +using NUnit.Framework; +using Spring.Rest.Client.Testing; + +using Spring.Http; + +namespace Spring.Social.Dropbox.Api.Impl +{ + /// + /// Unit tests for the DropboxErrorHandler class. + /// + /// Bruno Baia + [TestFixture] + public class ErrorHandlerTests + { + protected DropboxTemplate dropbox; + protected MockRestServiceServer mockServer; + protected HttpHeaders responseHeaders; + + [SetUp] + public void Setup() + { + dropbox = new DropboxTemplate("CONSUMER_KEY", "CONSUMER_SECRET", "ACCESS_TOKEN", "ACCESS_TOKEN_SECRET", AccessLevel.AppFolder); + mockServer = MockRestServiceServer.CreateServer(dropbox.RestTemplate); + responseHeaders = new HttpHeaders(); + responseHeaders.ContentType = MediaType.APPLICATION_JSON; + } + + [TearDown] + public void TearDown() + { + mockServer.Verify(); + } + + [Test] + public void PathNotFound() + { + mockServer.ExpectNewRequest() + .AndExpectUri("https://api.dropbox.com/1/metadata/sandbox/Spring Social/Temp.txt") + .AndExpectMethod(HttpMethod.GET) + .AndRespondWith("{\"error\": \"Path '/Spring Social/Temp.txt' not found\"}", responseHeaders, HttpStatusCode.NotFound, ""); + +#if NET_4_0 || SILVERLIGHT_5 + dropbox.GetMetadataAsync("/Spring Social/Temp.txt") + .ContinueWith(task => + { + AssertDropboxApiException(task.Exception, "Path '/Spring Social/Temp.txt' not found", DropboxApiError.PathNotFound); + }) + .Wait(); +#else + try + { + dropbox.GetMetadata("/Spring Social/Temp.txt"); + Assert.Fail("Exception expected"); + } + catch (Exception ex) + { + AssertDropboxApiException(ex, "Path '/Spring Social/Temp.txt' not found", DropboxApiError.PathNotFound); + } +#endif + } + + + // tests helpers + +#if NET_4_0 || SILVERLIGHT_5 + private void AssertDropboxApiException(AggregateException ae, string expectedMessage, DropboxApiError error) + { + ae.Handle(ex => + { + if (ex is DropboxApiException) + { + Assert.AreEqual(expectedMessage, ex.Message); + Assert.AreEqual(error, ((DropboxApiException)ex).Error); + return true; + } + return false; + }); + } +#else + private void AssertDropboxApiException(Exception ex, string expectedMessage, DropboxApiError error) + { + if (ex is DropboxApiException) + { + Assert.AreEqual(expectedMessage, ex.Message); + Assert.AreEqual(error, ((DropboxApiException)ex).Error); + } + else + { + Assert.Fail("DropboxApiException expected"); + } + } +#endif + } +} diff --git a/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2008-NET20.csproj b/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2008-NET20.csproj index 626558f..db9ae9c 100644 --- a/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2008-NET20.csproj +++ b/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2008-NET20.csproj @@ -99,6 +99,7 @@ + diff --git a/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2008-NET35.csproj b/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2008-NET35.csproj index 2fac282..cf7d6ea 100644 --- a/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2008-NET35.csproj +++ b/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2008-NET35.csproj @@ -99,6 +99,7 @@ + diff --git a/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2010-NET40.csproj b/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2010-NET40.csproj index 88528bd..a06b68b 100644 --- a/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2010-NET40.csproj +++ b/test/Spring.Social.Dropbox.Tests/Spring.Social.Dropbox.Tests.2010-NET40.csproj @@ -116,6 +116,7 @@ +