Skip to content

Commit

Permalink
improved error messages when reading or writing files fails
Browse files Browse the repository at this point in the history
  • Loading branch information
cebe committed Oct 24, 2019
1 parent 32802d8 commit aed871a
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 4 deletions.
3 changes: 3 additions & 0 deletions bin/php-openapi
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ function read_input($inputFile, $inputFormat)
} catch (Symfony\Component\Yaml\Exception\ParseException $e) {
error($e->getMessage());
exit(1);
} catch (cebe\openapi\exceptions\IOException $e) {
error($e->getMessage());
exit(1);
}
return $openApi;
}
Expand Down
19 changes: 17 additions & 2 deletions src/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace cebe\openapi;

use cebe\openapi\exceptions\IOException;
use cebe\openapi\exceptions\TypeErrorException;
use cebe\openapi\exceptions\UnresolvableReferenceException;
use cebe\openapi\spec\OpenApi;
Expand Down Expand Up @@ -63,10 +64,17 @@ public static function readFromYaml(string $yaml, string $baseType = OpenApi::cl
* The type of the returned object depends on the `$baseType` argument.
* @throws TypeErrorException in case invalid spec data is supplied.
* @throws UnresolvableReferenceException in case references could not be resolved.
* @throws IOException when the file is not readable.
*/
public static function readFromJsonFile(string $fileName, string $baseType = OpenApi::class, $resolveReferences = true): SpecObjectInterface
{
$spec = static::readFromJson(file_get_contents($fileName), $baseType);
$fileContent = file_get_contents($fileName);
if ($fileContent === false) {
$e = new IOException("Failed to read file: '$fileName'");
$e->fileName = $fileName;
throw $e;
}
$spec = static::readFromJson($fileContent, $baseType);
$spec->setReferenceContext(new ReferenceContext($spec, $fileName));
if ($resolveReferences) {
$spec->resolveReferences();
Expand All @@ -89,10 +97,17 @@ public static function readFromJsonFile(string $fileName, string $baseType = Ope
* The type of the returned object depends on the `$baseType` argument.
* @throws TypeErrorException in case invalid spec data is supplied.
* @throws UnresolvableReferenceException in case references could not be resolved.
* @throws IOException when the file is not readable.
*/
public static function readFromYamlFile(string $fileName, string $baseType = OpenApi::class, $resolveReferences = true): SpecObjectInterface
{
$spec = static::readFromYaml(file_get_contents($fileName), $baseType);
$fileContent = file_get_contents($fileName);
if ($fileContent === false) {
$e = new IOException("Failed to read file: '$fileName'");
$e->fileName = $fileName;
throw $e;
}
$spec = static::readFromYaml($fileContent, $baseType);
$spec->setReferenceContext(new ReferenceContext($spec, $fileName));
if ($resolveReferences) {
$spec->resolveReferences();
Expand Down
11 changes: 9 additions & 2 deletions src/Writer.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace cebe\openapi;

use cebe\openapi\exceptions\IOException;
use cebe\openapi\spec\OpenApi;
use Symfony\Component\Yaml\Yaml;

Expand Down Expand Up @@ -40,19 +41,25 @@ public static function writeToYaml(SpecObjectInterface $object): string
* Write OpenAPI spec object to JSON file.
* @param SpecObjectInterface|OpenApi the OpenApi object instance.
* @param string $fileName file name to write to.
* @throws IOException when writing the file fails.
*/
public static function writeToJsonFile(SpecObjectInterface $object, string $fileName): void
{
file_put_contents($fileName, static::writeToJson($object));
if (file_put_contents($fileName, static::writeToJson($object)) === false) {
throw new IOException("Failed to write file: '$fileName'");
}
}

/**
* Write OpenAPI spec object to YAML file.
* @param SpecObjectInterface|OpenApi the OpenApi object instance.
* @param string $fileName file name to write to.
* @throws IOException when writing the file fails.
*/
public static function writeToYamlFile(SpecObjectInterface $object, string $fileName): void
{
file_put_contents($fileName, static::writeToYaml($object));
if (file_put_contents($fileName, static::writeToYaml($object)) === false) {
throw new IOException("Failed to write file: '$fileName'");
}
}
}
20 changes: 20 additions & 0 deletions src/exceptions/IOException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/**
* @copyright Copyright (c) 2018 Carsten Brandt <[email protected]> and contributors
* @license https://github.com/cebe/php-openapi/blob/master/LICENSE
*/

namespace cebe\openapi\exceptions;

/**
* This exception is thrown when reading or writing of a file fails.
* @since 1.2.1
*/
class IOException extends \Exception
{
/**
* @var string|null if available, the name of the affected file.
*/
public $fileName;
}
20 changes: 20 additions & 0 deletions src/spec/Reference.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace cebe\openapi\spec;

use cebe\openapi\DocumentContextInterface;
use cebe\openapi\exceptions\IOException;
use cebe\openapi\exceptions\TypeErrorException;
use cebe\openapi\exceptions\UnresolvableReferenceException;
use cebe\openapi\json\InvalidJsonPointerSyntaxException;
Expand Down Expand Up @@ -156,6 +157,12 @@ public function resolve(ReferenceContext $context = null)
}
}
$jsonReference = $this->_jsonReference;
if ($jsonReference === null) {
if ($context->throwException) {
throw new UnresolvableReferenceException(implode("\n", $this->getErrors()));
}
return $this;
}
try {
if ($jsonReference->getDocumentUri() === '') {
// resolve in current document
Expand Down Expand Up @@ -204,6 +211,14 @@ public function resolve(ReferenceContext $context = null)
$this->_errors[] = $message;
$this->_jsonReference = null;
return $this;
} catch (UnresolvableReferenceException $e) {
$e->context = $this->getDocumentPosition();
if ($context->throwException) {
throw $e;
}
$this->_errors[] = $e->getMessage();
$this->_jsonReference = null;
return $this;
}
}

Expand All @@ -214,6 +229,11 @@ private function fetchReferencedFile($uri)
{
try {
$content = file_get_contents($uri);
if ($content === false) {
$e = new IOException("Failed to read file: '$uri'");
$e->fileName = $uri;
throw $e;
}
// TODO lazy content detection, should probably be improved
if (strpos(ltrim($content), '{') === 0) {
return json_decode($content, true);
Expand Down

0 comments on commit aed871a

Please sign in to comment.