Skip to content

Commit

Permalink
Merge pull request #717 from mlocati/centralize-error-handling
Browse files Browse the repository at this point in the history
Centralize error handling functions, fix #715
  • Loading branch information
mlocati committed Jun 3, 2019
2 parents 19a5897 + 25a7150 commit fb6fb3b
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 67 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# CHANGELOG

### NEXT (YYYY-MM-DD)

* Silence call to `\Imagick::setImageOpacity()` in order to prevent deprecation error with Imagick 3.4.4 and ImageMagick 6 (#715, @samdark, @mlocati)

### 1.2.0 (2018-12-07)
* `ExifMetadataReader` now returns all the available metadata, not only EXIF and IFD0 (#701, @mlocati)
Expand Down
35 changes: 2 additions & 33 deletions src/Gd/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace Imagine\Gd;

use Exception;
use Imagine\Exception\InvalidArgumentException;
use Imagine\Exception\OutOfBoundsException;
use Imagine\Exception\RuntimeException;
Expand All @@ -28,7 +27,7 @@
use Imagine\Image\Point;
use Imagine\Image\PointInterface;
use Imagine\Image\ProfileInterface;
use Throwable;
use Imagine\Utils\ErrorHandling;

/**
* Image implementation using the GD library.
Expand Down Expand Up @@ -666,7 +665,7 @@ private function saveOrOutput($format, array $options, $filename = null)
break;
}

$this->withExceptionHandler(function () use ($save, $args) {
ErrorHandling::throwingRuntimeException(E_WARNING | E_NOTICE, function () use ($save, $args) {
if (false === call_user_func_array($save, $args)) {
throw new RuntimeException('Save operation failed');
}
Expand Down Expand Up @@ -767,36 +766,6 @@ private function supported($format = null)
return is_string($format) && isset($formats[$format]);
}

/**
* @param callable $callback
*
* @throws \Imagine\Exception\RuntimeException
* @throws \Exception
* @throws \Throwable
*/
private function withExceptionHandler($callback)
{
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
if (0 === error_reporting()) {
return;
}

throw new RuntimeException($errstr, $errno, new \ErrorException($errstr, 0, $errno, $errfile, $errline));
}, E_WARNING | E_NOTICE);
$exception = null;
try {
$callback();
} catch (Exception $x) {
$exception = $x;
} catch (Throwable $x) {
$exception = $x;
}
restore_error_handler();
if ($exception !== null) {
throw $exception;
}
}

/**
* Get the mime type based on format.
*
Expand Down
26 changes: 3 additions & 23 deletions src/Gd/Imagine.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Imagine\Image\Palette\Color\RGB as RGBColor;
use Imagine\Image\Palette\PaletteInterface;
use Imagine\Image\Palette\RGB;
use Imagine\Utils\ErrorHandling;

/**
* Imagine implementation using the GD library.
Expand Down Expand Up @@ -87,7 +88,7 @@ public function open($path)
$path = $loader->getPath();

$data = $loader->getData();
$resource = $this->withoutExceptionHandlers(function () use (&$data) {
$resource = ErrorHandling::ignoring(-1, function () use (&$data) {
return @imagecreatefromstring($data);
});

Expand Down Expand Up @@ -208,7 +209,7 @@ private function requireGdVersion($version)
*/
private function doLoad($string, MetadataBag $metadata)
{
$resource = $this->withoutExceptionHandlers(function () use (&$string) {
$resource = ErrorHandling::ignoring(-1, function () use (&$string) {
return @imagecreatefromstring($string);
});

Expand All @@ -218,25 +219,4 @@ private function doLoad($string, MetadataBag $metadata)

return $this->wrap($resource, new RGB(), $metadata);
}

/**
* @param callable $callback
*
* @return mixed
*/
private function withoutExceptionHandlers($callback)
{
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
}, -1);
try {
$result = $callback();
} catch (\Exception $x) {
$result = null;
} catch (\Throwable $x) {
$result = null;
}
restore_error_handler();

return $result;
}
}
15 changes: 7 additions & 8 deletions src/Image/Metadata/ExifMetadataReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Imagine\Exception\NotSupportedException;
use Imagine\File\Loader;
use Imagine\File\LoaderInterface;
use Imagine\Utils\ErrorHandling;

/**
* Metadata driven by Exif information.
Expand Down Expand Up @@ -99,18 +100,16 @@ private function doReadData($data)
*/
private function extract($path)
{
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
if (error_reporting() !== 0) {
throw new \Exception($errstr, $errno);
}
}, E_WARNING | E_NOTICE);
try {
$exifData = @exif_read_data($path, null, true, false);
$exifData = ErrorHandling::ignoring(-1, function () use ($path) {
return @exif_read_data($path, null, true, false);
});
} catch (\Exception $e) {
$exifData = false;
} catch (\Throwable $e) {
$exifData = false;
}
restore_error_handler();
if ($exifData === false) {
if (!is_array($exifData)) {
return array();
}

Expand Down
10 changes: 9 additions & 1 deletion src/Imagick/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use Imagine\Image\Point;
use Imagine\Image\PointInterface;
use Imagine\Image\ProfileInterface;
use Imagine\Utils\ErrorHandling;

/**
* Image implementation using the Imagick PHP extension.
Expand Down Expand Up @@ -243,7 +244,14 @@ public function paste(ImageInterface $image, PointInterface $start, $alpha = 100
$pasteMe = $image->imagick;
} elseif ($alpha > 0) {
$pasteMe = $image->cloneImagick();
$pasteMe->setImageOpacity($alpha / 100);
// setImageOpacity was replaced with setImageAlpha in php-imagick v3.4.3
if (method_exists($pasteMe, 'setImageAlpha')) {
$pasteMe->setImageAlpha($alpha / 100);
} else {
ErrorHandling::ignoring(E_DEPRECATED, function () use ($pasteMe, $alpha) {
$pasteMe->setImageOpacity($alpha / 100);
});
}
} else {
$pasteMe = null;
}
Expand Down
5 changes: 4 additions & 1 deletion src/Imagick/Imagine.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Imagine\Image\Palette\Color\ColorInterface;
use Imagine\Image\Palette\Grayscale;
use Imagine\Image\Palette\RGB;
use Imagine\Utils\ErrorHandling;

/**
* Imagine implementation using the Imagick PHP extension.
Expand Down Expand Up @@ -106,7 +107,9 @@ public function create(BoxInterface $size, ColorInterface $color = null)
if (method_exists($imagick, 'setImageAlpha')) {
$imagick->setImageAlpha($pixel->getColorValue(\Imagick::COLOR_ALPHA));
} else {
$imagick->setImageOpacity($pixel->getColorValue(\Imagick::COLOR_ALPHA));
ErrorHandling::ignoring(E_DEPRECATED, function () use ($imagick, $pixel) {
$imagick->setImageOpacity($pixel->getColorValue(\Imagick::COLOR_ALPHA));
});
}
}

Expand Down
93 changes: 93 additions & 0 deletions src/Utils/ErrorHandling.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

/*
* This file is part of the Imagine package.
*
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Imagine\Utils;

use ErrorException;
use Exception;
use Imagine\Exception\RuntimeException;
use Throwable;

class ErrorHandling
{
/**
* Call a callback ignoring $flags warnings.
*
* @param int $flags The flags to be ignored (eg E_WARNING | E_NOTICE)
* @param callable $callback The callable to be called
*
* @throws \Exception Throws an Exception if $callback throws an Exception
* @throws \Throwable Throws an Throwable if $callback throws an Throwable
*
* @return mixed Returns the result of $callback
*/
public static function ignoring($flags, $callback)
{
set_error_handler(
function () {
},
$flags
);
try {
$result = $callback();
$exception = null;
} catch (Exception $x) {
$exception = $x;
} catch (Throwable $x) {
$exception = $x;
}
restore_error_handler();
if ($exception !== null) {
throw $exception;
}

return $result;
}

/**
* Call a callback and throws a RuntimeException if a $flags warning is thrown.
*
* @param int $flags The flags to be intercepted (eg E_WARNING | E_NOTICE)
* @param callable $callback The callable to be called
*
* @throws RuntimeException
* @throws \Imagine\Exception\RuntimeException
* @throws \Exception
* @throws \Throwable
*
* @return mixed Returns the result of $callback
*/
public static function throwingRuntimeException($flags, $callback)
{
set_error_handler(
function ($errno, $errstr, $errfile, $errline) {
if (error_reporting() !== 0) {
throw new RuntimeException($errstr, $errno, new ErrorException($errstr, 0, $errno, $errfile, $errline));
}
},
$flags
);
try {
$result = $callback();
$exception = null;
} catch (Exception $x) {
$exception = $x;
} catch (Throwable $x) {
$exception = $x;
}
restore_error_handler();
if ($exception !== null) {
throw $exception;
}

return $result;
}
}

0 comments on commit fb6fb3b

Please sign in to comment.