001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    package org.apache.hadoop.fs;
019    
020    import java.io.IOException;
021    
022    /**
023     * Exceptions based on standard posix/linux style exceptions for path related
024     * errors. Returns an exception with the format "path: standard error string".
025     * 
026     * This exception corresponds to Error Input/ouput(EIO)
027     */
028    public class PathIOException extends IOException {
029      static final long serialVersionUID = 0L;
030      private static final String EIO = "Input/output error";
031      // NOTE: this really should be a Path, but a Path is buggy and won't
032      // return the exact string used to construct the path, and it mangles
033      // uris with no authority
034      private String operation;
035      private String path;
036      private String targetPath;
037    
038      /**
039       * Constructor a generic I/O error exception
040       *  @param path for the exception
041       */
042      public PathIOException(String path) {
043        this(path, EIO);
044      }
045    
046      /**
047       * Appends the text of a Throwable to the default error message
048       * @param path for the exception
049       * @param cause a throwable to extract the error message
050       */
051      public PathIOException(String path, Throwable cause) {
052        this(path, EIO, cause);
053      }
054    
055      /**
056       * Avoid using this method.  Use a subclass of PathIOException if
057       * possible.
058       * @param path for the exception
059       * @param error custom string to use an the error text
060       */
061      public PathIOException(String path, String error) {
062        super(error);
063        this.path = path;
064      }
065    
066      protected PathIOException(String path, String error, Throwable cause) {
067        super(error, cause);
068        this.path = path;
069      }
070    
071      /** Format:
072       * cmd: {operation} `path' {to `target'}: error string
073       */
074      @Override
075      public String getMessage() {
076        StringBuilder message = new StringBuilder();
077        if (operation != null) {
078          message.append(operation + " ");
079        }
080        message.append(formatPath(path));
081        if (targetPath != null) {
082          message.append(" to " + formatPath(targetPath));
083        }
084        message.append(": " + super.getMessage());
085        if (getCause() != null) {
086          message.append(": " + getCause().getMessage());
087        }
088        return message.toString();
089      }
090    
091      /** @return Path that generated the exception */
092      public Path getPath()  { return new Path(path); }
093    
094      /** @return Path if the operation involved copying or moving, else null */
095      public Path getTargetPath() {
096        return (targetPath != null) ? new Path(targetPath) : null;
097      }    
098      
099      /**
100       * Optional operation that will preface the path
101       * @param operation a string
102       */
103      public void setOperation(String operation) {
104        this.operation = operation;
105      }
106      
107      /**
108       * Optional path if the exception involved two paths, ex. a copy operation
109       * @param targetPath the of the operation
110       */
111      public void setTargetPath(String targetPath) {
112        this.targetPath = targetPath;
113      }
114      
115      private String formatPath(String path) {
116        return "`" + path + "'";
117      }
118    }