cleaner conversion of errors to exceptions

This commit is contained in:
Robin Appelman 2016-12-08 17:15:31 +01:00
commit c1afd721f2
3 changed files with 55 additions and 57 deletions

View file

@ -16,4 +16,23 @@ class Exception extends \Exception {
return new Exception($message, $error);
}
/**
* @param array $exceptionMap
* @param mixed $error
* @param string $path
* @return Exception
*/
static public function fromMap(array $exceptionMap, $error, $path) {
if (isset($exceptionMap[$error])) {
$exceptionClass = $exceptionMap[$error];
if (is_numeric($error)) {
return new $exceptionClass($path, $error);
} else {
return new $exceptionClass($path);
}
} else {
return Exception::unknown($path, $error);
}
}
}

View file

@ -7,16 +7,7 @@
namespace Icewind\SMB;
use Icewind\SMB\Exception\AlreadyExistsException;
use Icewind\SMB\Exception\ConnectionRefusedException;
use Icewind\SMB\Exception\Exception;
use Icewind\SMB\Exception\ForbiddenException;
use Icewind\SMB\Exception\HostDownException;
use Icewind\SMB\Exception\InvalidTypeException;
use Icewind\SMB\Exception\NoRouteToHostException;
use Icewind\SMB\Exception\NotEmptyException;
use Icewind\SMB\Exception\NotFoundException;
use Icewind\SMB\Exception\TimedOutException;
/**
* Low level wrapper for libsmbclient-php for error handling
@ -31,36 +22,28 @@ class NativeState {
protected $connected = false;
// todo replace with static once <5.6 support is dropped
// see error.h
private static $exceptionMap = [
1 => '\Icewind\SMB\Exception\ForbiddenException',
2 => '\Icewind\SMB\Exception\NotFoundException',
13 => '\Icewind\SMB\Exception\ForbiddenException',
17 => '\Icewind\SMB\Exception\AlreadyExistsException',
20 => '\Icewind\SMB\Exception\InvalidTypeException',
21 => '\Icewind\SMB\Exception\InvalidTypeException',
39 => '\Icewind\SMB\Exception\NotEmptyException',
110 => '\Icewind\SMB\Exception\TimedOutException',
111 => '\Icewind\SMB\Exception\ConnectionRefusedException',
112 => '\Icewind\SMB\Exception\HostDownException',
113 => '\Icewind\SMB\Exception\NoRouteToHostException'
];
protected function handleError($path) {
$error = smbclient_state_errno($this->state);
switch ($error) {
// see error.h
case 0;
if ($error === 0) {
return;
case 1:
case 13:
throw new ForbiddenException($path, $error);
case 2:
throw new NotFoundException($path, $error);
case 17:
throw new AlreadyExistsException($path, $error);
case 20:
throw new InvalidTypeException($path, $error);
case 21:
throw new InvalidTypeException($path, $error);
case 39:
throw new NotEmptyException($path, $error);
case 110:
throw new TimedOutException($path, $error);
case 111:
throw new ConnectionRefusedException($path, $error);
case 112:
throw new HostDownException($path, $error);
case 113:
throw new NoRouteToHostException($path, $error);
default:
throw Exception::unknown($path, $error);
}
throw Exception::fromMap(self::$exceptionMap, $error, $path);
}
protected function testResult($result, $uri) {

View file

@ -27,6 +27,20 @@ class Parser {
*/
protected $timeZoneProvider;
// todo replace with static once <5.6 support is dropped
// see error.h
private static $exceptionMap = [
ErrorCodes::PathNotFound => '\Icewind\SMB\Exception\NotFoundException',
ErrorCodes::ObjectNotFound => '\Icewind\SMB\Exception\NotFoundException',
ErrorCodes::NoSuchFile => '\Icewind\SMB\Exception\NotFoundException',
ErrorCodes::NameCollision => '\Icewind\SMB\Exception\AlreadyExistsException',
ErrorCodes::AccessDenied => '\Icewind\SMB\Exception\AccessDeniedException',
ErrorCodes::DirectoryNotEmpty => '\Icewind\SMB\Exception\NotEmptyException',
ErrorCodes::FileIsADirectory => '\Icewind\SMB\Exception\InvalidTypeException',
ErrorCodes::NotADirectory => '\Icewind\SMB\Exception\InvalidTypeException',
ErrorCodes::SharingViolation => '\Icewind\SMB\Exception\FileInUseException'
];
/**
* @param \Icewind\SMB\TimeZoneProvider $timeZoneProvider
*/
@ -55,25 +69,7 @@ class Parser {
throw new InvalidResourceException('Failed opening local file "' . $localPath . '" for writing');
}
switch ($error) {
case ErrorCodes::PathNotFound:
case ErrorCodes::ObjectNotFound:
case ErrorCodes::NoSuchFile:
throw new NotFoundException($path);
case ErrorCodes::NameCollision:
throw new AlreadyExistsException($path);
case ErrorCodes::AccessDenied:
throw new AccessDeniedException($path);
case ErrorCodes::DirectoryNotEmpty:
throw new NotEmptyException($path);
case ErrorCodes::FileIsADirectory:
case ErrorCodes::NotADirectory:
throw new InvalidTypeException($path);
case ErrorCodes::SharingViolation:
throw new FileInUseException($path);
default:
throw Exception::unknown($path, $error);
}
throw Exception::fromMap(self::$exceptionMap, $error, $path);
}
/**
@ -135,7 +131,7 @@ class Parser {
return [
'mtime' => strtotime($data['write_time']),
'mode' => hexdec(substr($data['attributes'], strpos($data['attributes'], '('), -1)),
'size' => intval(explode(' ', $data['stream'])[1])
'size' => isset($data['stream']) ? intval(explode(' ', $data['stream'])[1]) : 0
];
}