mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	GUAC-1161: Generalize APICredentialError into APIError. Provide consistent error responses for all REST endpoints.
This commit is contained in:
		| @@ -1,102 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2015 Glyptodon LLC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| package org.glyptodon.guacamole.net.basic.rest; | ||||
|  | ||||
| import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo; | ||||
|  | ||||
| /** | ||||
|  * Represents an error related to either invalid or insufficient credentials | ||||
|  * submitted to a REST endpoint. | ||||
|  * | ||||
|  * @author Michael Jumper | ||||
|  */ | ||||
| public class APICredentialError extends APIError { | ||||
|  | ||||
|     /** | ||||
|      * The required credentials. | ||||
|      */ | ||||
|     private final CredentialsInfo info; | ||||
|  | ||||
|     /** | ||||
|      * The type of error that occurred. | ||||
|      */ | ||||
|     private final Type type; | ||||
|  | ||||
|     /** | ||||
|      * All possible types of credential errors. | ||||
|      */ | ||||
|     public enum Type { | ||||
|  | ||||
|         /** | ||||
|          * The credentials provided were invalid. | ||||
|          */ | ||||
|         INVALID, | ||||
|  | ||||
|         /** | ||||
|          * The credentials provided were not necessarily invalid, but were not | ||||
|          * sufficient to determine validity. | ||||
|          */ | ||||
|         INSUFFICIENT | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a new APICredentialError with the specified error message and | ||||
|      * credentials information. | ||||
|      * | ||||
|      * @param type | ||||
|      *     The type of error that occurred. | ||||
|      * | ||||
|      * @param message | ||||
|      *     The error message. | ||||
|      * | ||||
|      * @param info | ||||
|      *     An object which describes the required credentials. | ||||
|      */ | ||||
|     public APICredentialError(Type type, String message, CredentialsInfo info) { | ||||
|         super(message); | ||||
|         this.type = type; | ||||
|         this.info = info; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the type of error that occurred. | ||||
|      * | ||||
|      * @return | ||||
|      *     The type of error that occurred. | ||||
|      */ | ||||
|     public Type getType() { | ||||
|         return type; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns an object which describes the required credentials. | ||||
|      * | ||||
|      * @return | ||||
|      *     An object which describes the required credentials. | ||||
|      */ | ||||
|     public CredentialsInfo getInfo() { | ||||
|         return info; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014 Glyptodon LLC | ||||
|  * Copyright (C) 2015 Glyptodon LLC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
| @@ -22,31 +22,161 @@ | ||||
|  | ||||
| package org.glyptodon.guacamole.net.basic.rest; | ||||
|  | ||||
| import java.util.Collection; | ||||
| import javax.ws.rs.core.Response; | ||||
| import org.glyptodon.guacamole.form.Parameter; | ||||
|  | ||||
| /** | ||||
|  * A simple object to represent an error to be sent from the REST API. | ||||
|  * Describes an error that occurred within a REST endpoint. | ||||
|  * | ||||
|  * @author James Muehlner | ||||
|  * @author Michael Jumper | ||||
|  */ | ||||
| public class APIError { | ||||
|      | ||||
|  | ||||
|     /** | ||||
|      * The error message. | ||||
|      */ | ||||
|     private final String message; | ||||
|  | ||||
|     /** | ||||
|      * Get the error message. | ||||
|      * @return The error message. | ||||
|      * All expected request parameters, if any. | ||||
|      */ | ||||
|     private final Collection<Parameter> expected; | ||||
|  | ||||
|     /** | ||||
|      * The type of error that occurred. | ||||
|      */ | ||||
|     private final Type type; | ||||
|  | ||||
|     /** | ||||
|      * All possible types of REST API errors. | ||||
|      */ | ||||
|     public enum Type { | ||||
|  | ||||
|         /** | ||||
|          * The requested operation could not be performed because the request | ||||
|          * itself was malformed. | ||||
|          */ | ||||
|         BAD_REQUEST(Response.Status.BAD_REQUEST), | ||||
|  | ||||
|         /** | ||||
|          * The credentials provided were invalid. | ||||
|          */ | ||||
|         INVALID_CREDENTIALS(Response.Status.FORBIDDEN), | ||||
|  | ||||
|         /** | ||||
|          * The credentials provided were not necessarily invalid, but were not | ||||
|          * sufficient to determine validity. | ||||
|          */ | ||||
|         INSUFFICIENT_CREDENTIALS(Response.Status.FORBIDDEN), | ||||
|  | ||||
|         /** | ||||
|          * An internal server error has occurred. | ||||
|          */ | ||||
|         INTERNAL_ERROR(Response.Status.INTERNAL_SERVER_ERROR), | ||||
|  | ||||
|         /** | ||||
|          * An object related to the request does not exist. | ||||
|          */ | ||||
|         NOT_FOUND(Response.Status.NOT_FOUND), | ||||
|  | ||||
|         /** | ||||
|          * Permission was denied to perform the requested operation. | ||||
|          */ | ||||
|         PERMISSION_DENIED(Response.Status.FORBIDDEN); | ||||
|  | ||||
|         /** | ||||
|          * The HTTP status associated with this error type. | ||||
|          */ | ||||
|         private final Response.Status status; | ||||
|  | ||||
|         /** | ||||
|          * Defines a new error type associated with the given HTTP status. | ||||
|          * | ||||
|          * @param status | ||||
|          *     The HTTP status to associate with the error type. | ||||
|          */ | ||||
|         Type(Response.Status status) { | ||||
|             this.status = status; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the HTTP status associated with this error type. | ||||
|          * | ||||
|          * @return | ||||
|          *     The HTTP status associated with this error type. | ||||
|          */ | ||||
|         public Response.Status getStatus() { | ||||
|             return status; | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a new APIError with the specified error message. | ||||
|      * | ||||
|      * @param type | ||||
|      *     The type of error that occurred. | ||||
|      * | ||||
|      * @param message | ||||
|      *     The error message. | ||||
|      */ | ||||
|     public APIError(Type type, String message) { | ||||
|         this.type     = type; | ||||
|         this.message  = message; | ||||
|         this.expected = null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a new APIError with the specified error message and parameter | ||||
|      * information. | ||||
|      * | ||||
|      * @param type | ||||
|      *     The type of error that occurred. | ||||
|      * | ||||
|      * @param message | ||||
|      *     The error message. | ||||
|      * | ||||
|      * @param expected | ||||
|      *     All parameters expected in the original request, or now required as | ||||
|      *     a result of the original request. | ||||
|      */ | ||||
|     public APIError(Type type, String message, Collection<Parameter> expected) { | ||||
|         this.type     = type; | ||||
|         this.message  = message; | ||||
|         this.expected = expected; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the type of error that occurred. | ||||
|      * | ||||
|      * @return | ||||
|      *     The type of error that occurred. | ||||
|      */ | ||||
|     public Type getType() { | ||||
|         return type; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns an object which describes the required credentials. | ||||
|      * | ||||
|      * @return | ||||
|      *     An object which describes the required credentials. | ||||
|      */ | ||||
|     public Collection<Parameter> getExpected() { | ||||
|         return expected; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a human-readable error message describing the error that | ||||
|      * occurred. | ||||
|      * | ||||
|      * @return | ||||
|      *     A human-readable error message. | ||||
|      */ | ||||
|     public String getMessage() { | ||||
|         return message; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * Create a new APIError with the specified error message. | ||||
|      * @param message The error message. | ||||
|      */ | ||||
|     public APIError(String message) { | ||||
|         this.message = message; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -27,6 +27,7 @@ import org.aopalliance.intercept.MethodInterceptor; | ||||
| import org.aopalliance.intercept.MethodInvocation; | ||||
| import org.glyptodon.guacamole.GuacamoleClientException; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.GuacamoleResourceNotFoundException; | ||||
| import org.glyptodon.guacamole.GuacamoleSecurityException; | ||||
| import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo; | ||||
| import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException; | ||||
| @@ -61,11 +62,11 @@ public class AuthProviderRESTExceptionWrapper implements MethodInterceptor { | ||||
|             if (message == null) | ||||
|                 message = "Permission denied."; | ||||
|  | ||||
|             throw new HTTPException(Response.Status.FORBIDDEN, new APICredentialError( | ||||
|                     APICredentialError.Type.INSUFFICIENT, | ||||
|                     message, | ||||
|                     e.getCredentialsInfo() | ||||
|             )); | ||||
|             throw new HTTPException( | ||||
|                 APIError.Type.INSUFFICIENT_CREDENTIALS, | ||||
|                 message, | ||||
|                 e.getCredentialsInfo().getParameters() | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         // The provided credentials are wrong | ||||
| @@ -76,11 +77,11 @@ public class AuthProviderRESTExceptionWrapper implements MethodInterceptor { | ||||
|             if (message == null) | ||||
|                 message = "Permission denied."; | ||||
|  | ||||
|             throw new HTTPException(Response.Status.FORBIDDEN, new APICredentialError( | ||||
|                     APICredentialError.Type.INVALID, | ||||
|                     message, | ||||
|                     e.getCredentialsInfo() | ||||
|             )); | ||||
|             throw new HTTPException( | ||||
|                 APIError.Type.INVALID_CREDENTIALS, | ||||
|                 message, | ||||
|                 e.getCredentialsInfo().getParameters() | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         // Generic permission denied | ||||
| @@ -91,10 +92,28 @@ public class AuthProviderRESTExceptionWrapper implements MethodInterceptor { | ||||
|             if (message == null) | ||||
|                 message = "Permission denied."; | ||||
|  | ||||
|             throw new HTTPException(Response.Status.FORBIDDEN, message); | ||||
|             throw new HTTPException( | ||||
|                 APIError.Type.PERMISSION_DENIED, | ||||
|                 message | ||||
|             ); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // Arbitrary resource not found | ||||
|         catch (GuacamoleResourceNotFoundException e) { | ||||
|  | ||||
|             // Generate default message | ||||
|             String message = e.getMessage(); | ||||
|             if (message == null) | ||||
|                 message = "Not found."; | ||||
|  | ||||
|             throw new HTTPException( | ||||
|                 APIError.Type.NOT_FOUND, | ||||
|                 message | ||||
|             ); | ||||
|  | ||||
|         } | ||||
|          | ||||
|         // Arbitrary bad requests | ||||
|         catch (GuacamoleClientException e) { | ||||
|  | ||||
| @@ -103,7 +122,10 @@ public class AuthProviderRESTExceptionWrapper implements MethodInterceptor { | ||||
|             if (message == null) | ||||
|                 message = "Invalid request."; | ||||
|  | ||||
|             throw new HTTPException(Response.Status.BAD_REQUEST, message); | ||||
|             throw new HTTPException( | ||||
|                 APIError.Type.BAD_REQUEST, | ||||
|                 message | ||||
|             ); | ||||
|  | ||||
|         } | ||||
|  | ||||
| @@ -116,7 +138,10 @@ public class AuthProviderRESTExceptionWrapper implements MethodInterceptor { | ||||
|                 message = "Unexpected server error."; | ||||
|  | ||||
|             logger.debug("Unexpected exception in REST endpoint.", e); | ||||
|             throw new HTTPException(Response.Status.INTERNAL_SERVER_ERROR, message); | ||||
|             throw new HTTPException( | ||||
|                 APIError.Type.INTERNAL_ERROR, | ||||
|                 message | ||||
|             ); | ||||
|  | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -22,37 +22,64 @@ | ||||
|  | ||||
| package org.glyptodon.guacamole.net.basic.rest; | ||||
|  | ||||
| import java.util.Collection; | ||||
| import javax.ws.rs.WebApplicationException; | ||||
| import javax.ws.rs.core.Response; | ||||
| import javax.ws.rs.core.Response.Status; | ||||
| import org.glyptodon.guacamole.form.Parameter; | ||||
|  | ||||
| /** | ||||
|  * An exception that will result in the given HTTP Status and message or entity  | ||||
|  * being returned from the API layer. | ||||
|  *  | ||||
|  * An exception that will result in the given HTTP Status and error being | ||||
|  * returned from the API layer. All error messages have the same format which | ||||
|  * is defined by APIError. | ||||
|  * | ||||
|  * @author James Muehlner | ||||
|  * @author Michael Jumper | ||||
|  */ | ||||
| public class HTTPException extends WebApplicationException { | ||||
|      | ||||
|  | ||||
|     /** | ||||
|      * Construct a new HTTPException with the given HTTP status and entity. | ||||
|      *  | ||||
|      * @param status The HTTP Status to use for the response. | ||||
|      * @param entity The entity to use as the body of the response. | ||||
|      * Construct a new HTTPException with the given error. All information | ||||
|      * associated with this new exception will be extracted from the given | ||||
|      * APIError. | ||||
|      * | ||||
|      * @param error | ||||
|      *     The error that occurred. | ||||
|      */ | ||||
|     public HTTPException(Status status, Object entity) { | ||||
|         super(Response.status(status).entity(entity).build()); | ||||
|     public HTTPException(APIError error) { | ||||
|         super(Response.status(error.getType().getStatus()).entity(error).build()); | ||||
|     } | ||||
|      | ||||
|  | ||||
|     /** | ||||
|      * Construct a new HTTPException with the given HTTP status and message. The | ||||
|      * message will be wrapped in an APIError container. | ||||
|      *  | ||||
|      * @param status The HTTP Status to use for the response. | ||||
|      * @param message The message to build the response entity with. | ||||
|      * Creates a new HTTPException with the given type and message. The | ||||
|      * corresponding APIError will be created from the provided information. | ||||
|      * | ||||
|      * @param type | ||||
|      *     The type of error that occurred. | ||||
|      * | ||||
|      * @param message | ||||
|      *     A human-readable message describing the error. | ||||
|      */ | ||||
|     public HTTPException(Status status, String message) { | ||||
|         super(Response.status(status).entity(new APIError(message)).build()); | ||||
|     public HTTPException(APIError.Type type, String message) { | ||||
|         this(new APIError(type, message)); | ||||
|     } | ||||
|      | ||||
|  | ||||
|     /** | ||||
|      * Creates a new HTTPException with the given type, message, and | ||||
|      * parameter information. The corresponding APIError will be created from | ||||
|      * the provided information. | ||||
|      * | ||||
|      * @param type | ||||
|      *     The type of error that occurred. | ||||
|      * | ||||
|      * @param message | ||||
|      *     A human-readable message describing the error. | ||||
|      * | ||||
|      * @param expected | ||||
|      *     All parameters expected in the original request, or now required as | ||||
|      *     a result of the original request. | ||||
|      */ | ||||
|     public HTTPException(APIError.Type type, String message, Collection<Parameter> expected) { | ||||
|         this(new APIError(type, message, expected)); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -35,7 +35,6 @@ import javax.ws.rs.Produces; | ||||
| import javax.ws.rs.core.Context; | ||||
| import javax.ws.rs.core.MediaType; | ||||
| import javax.ws.rs.core.MultivaluedMap; | ||||
| import javax.ws.rs.core.Response.Status; | ||||
| import javax.xml.bind.DatatypeConverter; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.auth.AuthenticationProvider; | ||||
| @@ -44,6 +43,7 @@ import org.glyptodon.guacamole.net.auth.UserContext; | ||||
| import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo; | ||||
| import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; | ||||
| import org.glyptodon.guacamole.net.basic.GuacamoleSession; | ||||
| import org.glyptodon.guacamole.net.basic.rest.APIError; | ||||
| import org.glyptodon.guacamole.net.basic.rest.APIRequest; | ||||
| import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; | ||||
| import org.glyptodon.guacamole.net.basic.rest.HTTPException; | ||||
| @@ -290,7 +290,7 @@ public class TokenRESTService { | ||||
|          | ||||
|         GuacamoleSession session = tokenSessionMap.remove(authToken); | ||||
|         if (session == null) | ||||
|             throw new HTTPException(Status.NOT_FOUND, "No such token."); | ||||
|             throw new HTTPException(APIError.Type.NOT_FOUND, "No such token."); | ||||
|  | ||||
|         session.invalidate(); | ||||
|  | ||||
|   | ||||
| @@ -39,8 +39,6 @@ import javax.ws.rs.Produces; | ||||
| import javax.ws.rs.QueryParam; | ||||
| import javax.ws.rs.core.Context; | ||||
| import javax.ws.rs.core.MediaType; | ||||
| import javax.ws.rs.core.Response; | ||||
| import javax.ws.rs.core.Response.Status; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.GuacamoleResourceNotFoundException; | ||||
| import org.glyptodon.guacamole.net.auth.AuthenticationProvider; | ||||
| @@ -53,6 +51,7 @@ import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; | ||||
| import org.glyptodon.guacamole.net.auth.permission.Permission; | ||||
| import org.glyptodon.guacamole.net.auth.permission.SystemPermission; | ||||
| import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet; | ||||
| import org.glyptodon.guacamole.net.basic.rest.APIError; | ||||
| import org.glyptodon.guacamole.net.basic.rest.APIPatch; | ||||
| import static org.glyptodon.guacamole.net.basic.rest.APIPatch.Operation.add; | ||||
| import static org.glyptodon.guacamole.net.basic.rest.APIPatch.Operation.remove; | ||||
| @@ -276,12 +275,12 @@ public class UserRESTService { | ||||
|  | ||||
|         // Validate data and path are sane | ||||
|         if (!user.getUsername().equals(username)) | ||||
|             throw new HTTPException(Response.Status.BAD_REQUEST, | ||||
|             throw new HTTPException(APIError.Type.BAD_REQUEST, | ||||
|                     "Username in path does not match username provided JSON data."); | ||||
|          | ||||
|         // A user may not use this endpoint to modify himself | ||||
|         if (userContext.self().getIdentifier().equals(user.getUsername())) { | ||||
|             throw new HTTPException(Response.Status.FORBIDDEN, | ||||
|             throw new HTTPException(APIError.Type.PERMISSION_DENIED, | ||||
|                     "Permission denied."); | ||||
|         } | ||||
|  | ||||
| @@ -336,7 +335,7 @@ public class UserRESTService { | ||||
|          | ||||
|         // Verify that the old password was correct  | ||||
|         if (authProvider.getUserContext(credentials) == null) { | ||||
|             throw new HTTPException(Response.Status.FORBIDDEN, | ||||
|             throw new HTTPException(APIError.Type.PERMISSION_DENIED, | ||||
|                     "Permission denied."); | ||||
|         } | ||||
|          | ||||
| @@ -467,7 +466,7 @@ public class UserRESTService { | ||||
|  | ||||
|             // Unsupported patch operation | ||||
|             default: | ||||
|                 throw new HTTPException(Status.BAD_REQUEST, | ||||
|                 throw new HTTPException(APIError.Type.BAD_REQUEST, | ||||
|                         "Unsupported patch operation: \"" + operation + "\""); | ||||
|  | ||||
|         } | ||||
| @@ -586,7 +585,7 @@ public class UserRESTService { | ||||
|  | ||||
|             // Otherwise, the path is not supported | ||||
|             else | ||||
|                 throw new HTTPException(Status.BAD_REQUEST, "Unsupported patch path: \"" + path + "\""); | ||||
|                 throw new HTTPException(APIError.Type.BAD_REQUEST, "Unsupported patch path: \"" + path + "\""); | ||||
|  | ||||
|         } // end for each patch operation | ||||
|          | ||||
|   | ||||
							
								
								
									
										122
									
								
								guacamole/src/main/webapp/app/rest/types/Error.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								guacamole/src/main/webapp/app/rest/types/Error.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| /* | ||||
|  * Copyright (C) 2015 Glyptodon LLC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Service which defines the Error class. | ||||
|  */ | ||||
| angular.module('rest').factory('Error', [function defineError() { | ||||
|  | ||||
|     /** | ||||
|      * The object returned by REST API calls when an error occurs. | ||||
|      * | ||||
|      * @constructor | ||||
|      * @param {Error|Object} [template={}] | ||||
|      *     The object whose properties should be copied within the new | ||||
|      *     Error. | ||||
|      */ | ||||
|     var Error = function Error(template) { | ||||
|  | ||||
|         // Use empty object by default | ||||
|         template = template || {}; | ||||
|  | ||||
|         /** | ||||
|          * A human-readable message describing the error that occurred. | ||||
|          * | ||||
|          * @type String | ||||
|          */ | ||||
|         this.message = template.message; | ||||
|  | ||||
|         /** | ||||
|          * The type string defining which values this parameter may contain, | ||||
|          * as well as what properties are applicable. Valid types are listed | ||||
|          * within Error.Type. | ||||
|          * | ||||
|          * @type String | ||||
|          * @default Error.Type.INTERNAL_ERROR | ||||
|          */ | ||||
|         this.type = template.type || Error.Type.INTERNAL_ERROR; | ||||
|  | ||||
|         /** | ||||
|          * Any parameters which were expected in the original request, or are | ||||
|          * now expected as a result of the original request, if any. If no | ||||
|          * such information is available, this will be null. | ||||
|          * | ||||
|          * @type Field[] | ||||
|          */ | ||||
|         this.expected = template.expected; | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * All valid field types. | ||||
|      */ | ||||
|     Error.Type = { | ||||
|  | ||||
|         /** | ||||
|          * The requested operation could not be performed because the request | ||||
|          * itself was malformed. | ||||
|          * | ||||
|          * @type String | ||||
|          */ | ||||
|         BAD_REQUEST : 'BAD_REQUEST', | ||||
|  | ||||
|         /** | ||||
|          * The credentials provided were invalid. | ||||
|          * | ||||
|          * @type String | ||||
|          */ | ||||
|         INVALID_CREDENTIALS : 'INVALID_CREDENTIALS', | ||||
|  | ||||
|         /** | ||||
|          * The credentials provided were not necessarily invalid, but were not | ||||
|          * sufficient to determine validity. | ||||
|          * | ||||
|          * @type String | ||||
|          */ | ||||
|         INSUFFICIENT_CREDENTIALS : 'INSUFFICIENT_CREDENTIALS', | ||||
|  | ||||
|         /** | ||||
|          * An internal server error has occurred. | ||||
|          * | ||||
|          * @type String | ||||
|          */ | ||||
|         INTERNAL_ERROR : 'INTERNAL_ERROR', | ||||
|  | ||||
|         /** | ||||
|          * An object related to the request does not exist. | ||||
|          * | ||||
|          * @type String | ||||
|          */ | ||||
|         NOT_FOUND : 'NOT_FOUND', | ||||
|  | ||||
|         /** | ||||
|          * Permission was denied to perform the requested operation. | ||||
|          * | ||||
|          * @type String | ||||
|          */ | ||||
|         PERMISSION_DENIED : 'PERMISSION_DENIED' | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     return Error; | ||||
|  | ||||
| }]); | ||||
		Reference in New Issue
	
	Block a user