Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #450: Add custom exceptions #454

Merged
merged 14 commits into from
May 25, 2022
6 changes: 3 additions & 3 deletions src/Actions/CreatesNewMarkdownPostFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Hyde\Framework\Actions;

use Exception;
use Hyde\Framework\Exceptions\FileConflictException;
use Hyde\Framework\Hyde;
use Illuminate\Support\Str;

Expand Down Expand Up @@ -95,14 +95,14 @@ public function __construct(
* @param bool $force Should the file be created even if a file with the same path already exists?
* @return string|false Returns the path to the file if successful, or false if the file could not be saved.
*
* @throws Exception if a file with the same slug already exists and the force flag is not set.
* @throws FileConflictException if a file with the same slug already exists and the force flag is not set.
*/
public function save(bool $force = false): string|false
{
$path = Hyde::path("_posts/$this->slug.md");

if ($force !== true && file_exists($path)) {
throw new Exception("File at $path already exists! ", 409);
throw new FileConflictException($path);
}

$arrayWithoutSlug = ((array) $this);
Expand Down
76 changes: 14 additions & 62 deletions src/Actions/CreatesNewPageSourceFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

namespace Hyde\Framework\Actions;

use Exception;
use Hyde\Framework\Exceptions\FileConflictException;
use Hyde\Framework\Exceptions\UnsupportedPageTypeException;
use Hyde\Framework\Hyde;
use Hyde\Framework\Models\BladePage;
use Hyde\Framework\Models\DocumentationPage;
Expand All @@ -16,32 +17,10 @@
*/
class CreatesNewPageSourceFile
{
/**
* The Page title.
*
* @var string
*/
public string $title;

/**
* The Page slug.
*/
public string $slug;
public string $outputPath;

/**
* The file path.
*/
public string $path;

/**
* Construct the class.
*
* @param string $title - The page title, will be used to generate the slug
* @param string $type - The page type, FQDN of the page class
* @param bool $force - Overwrite any existing files?
*
* @throws Exception if the page type is not supported or the file already exists
*/
public function __construct(string $title, string $type = MarkdownPage::class, public bool $force = false)
{
$this->title = $title;
Expand All @@ -50,25 +29,13 @@ public function __construct(string $title, string $type = MarkdownPage::class, p
$this->createPage($type);
}

/**
* Check if the file can be saved.
*
* @throws Exception if the file already exists and cannot be overwritten
*/
public function canSaveFile(string $path): void
{
if (file_exists($path) && ! $this->force) {
throw new Exception("File $path already exists!", 409);
throw new FileConflictException($path);
}
}

/**
* Create the page.
*
* @param string $type FQDN of the page class
*
* @throws Exception if the page type is not supported
*/
public function createPage(string $type): int|false
{
if ($type === MarkdownPage::class) {
Expand All @@ -82,39 +49,29 @@ public function createPage(string $type): int|false
return $this->createDocumentationFile();
}

throw new Exception('The page type must be either "markdown", "blade", or "documentation"');
throw new UnsupportedPageTypeException('The page type must be either "markdown", "blade", or "documentation"');
}

/**
* Create the Markdown file.
*
* @throws Exception if the file cannot be saved.
*/
public function createMarkdownFile(): int|false
{
$this->path = Hyde::path("_pages/$this->slug.md");
$this->outputPath = Hyde::path("_pages/$this->slug.md");

$this->canSaveFile($this->path);
$this->canSaveFile($this->outputPath);

return file_put_contents(
$this->path,
$this->outputPath,
"---\ntitle: $this->title\n---\n\n# $this->title\n"
);
}

/**
* Create the Blade file.
*
* @throws Exception if the file cannot be saved.
*/
public function createBladeFile(): int|false
{
$this->path = Hyde::path("_pages/$this->slug.blade.php");
$this->outputPath = Hyde::path("_pages/$this->slug.blade.php");

$this->canSaveFile($this->path);
$this->canSaveFile($this->outputPath);

return file_put_contents(
$this->path,
$this->outputPath,
<<<EOF
@extends('hyde::layouts.app')
@section('content')
Expand All @@ -130,19 +87,14 @@ public function createBladeFile(): int|false
);
}

/**
* Create the Documentation file.
*
* @throws Exception if the file cannot be saved.
*/
public function createDocumentationFile(): int|false
{
$this->path = Hyde::path("_docs/$this->slug.md");
$this->outputPath = Hyde::path("_docs/$this->slug.md");

$this->canSaveFile($this->path);
$this->canSaveFile($this->outputPath);

return file_put_contents(
$this->path,
$this->outputPath,
"# $this->title\n"
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Concerns/HasDateString.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trait HasDateString
public ?DateString $date = null;

/**
* @throws \Exception
* @throws \Hyde\Framework\Exceptions\CouldNotParseDateStringException
*/
public function constructDateString(): void
{
Expand Down
8 changes: 5 additions & 3 deletions src/Concerns/ValidatesExistence.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@

namespace Hyde\Framework\Concerns;

use Exception;
use Hyde\Framework\Exceptions\FileNotFoundException;
use Hyde\Framework\Hyde;

/**
* Validate the existence of a Page model's source file.
*
* @see \Tests\Unit\ValidatesExistenceTest
*/
trait ValidatesExistence
{
/**
* Check if a supplied source file exists or throw an exception.
*
* @throws Exception If the file does not exist.
* @throws FileNotFoundException If the file does not exist.
*/
public function validateExistence(string $model, string $slug): void
{
Expand All @@ -22,7 +24,7 @@ public function validateExistence(string $model, string $slug): void
$slug.$model::$fileExtension;

if (! file_exists(Hyde::path($filepath))) {
throw new Exception("File $filepath not found.", 404);
throw new FileNotFoundException($filepath);
}
}
}
10 changes: 10 additions & 0 deletions src/Exceptions/CouldNotParseDateStringException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Hyde\Framework\Exceptions;

use Exception;

class CouldNotParseDateStringException extends Exception
{
//
}
16 changes: 16 additions & 0 deletions src/Exceptions/FileConflictException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Hyde\Framework\Exceptions;

use Exception;

class FileConflictException extends Exception
{
protected $message = 'A file already exists at this path.';
protected $code = 409;

public function __construct(?string $path = null)
{
$this->message = $path ? "File already exists: {$path}" : $this->message;
}
}
16 changes: 16 additions & 0 deletions src/Exceptions/FileNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Hyde\Framework\Exceptions;

use Exception;

class FileNotFoundException extends Exception
{
protected $message = 'File not found.';
protected $code = 404;

public function __construct(?string $path = null)
{
$this->message = $path ? "File not found: {$path}" : $this->message;
}
}
16 changes: 16 additions & 0 deletions src/Exceptions/UnsupportedPageTypeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Hyde\Framework\Exceptions;

use Exception;

class UnsupportedPageTypeException extends Exception
{
protected $message = 'The page type is not supported.';
protected $code = 400;

public function __construct(?string $page = null)
{
$this->message = $page ? "The page type is not supported: {$page}" : $this->message;
}
}
3 changes: 0 additions & 3 deletions src/Hyde.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ public static function titleFromSlug(string $slug): string
return Str::title(str_replace('-', ' ', ($slug)));
}

/**
* @throws \Exception
*/
public static function getLatestPosts(): Collection
{
$collection = new Collection();
Expand Down
11 changes: 9 additions & 2 deletions src/Models/DateString.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
namespace Hyde\Framework\Models;

use DateTime;
use Hyde\Framework\Exceptions\CouldNotParseDateStringException;

/**
* Parse a date string and create normalized formats.
*
* @see \Tests\Unit\DateStringTest
*/
class DateString
{
Expand All @@ -27,13 +30,17 @@ class DateString
/**
* @param string $string
*
* @throws \Exception
* @throws \Hyde\Framework\Exceptions\CouldNotParseDateStringException
*/
public function __construct(string $string)
{
$this->string = $string;

$this->dateTimeObject = new DateTime($this->string);
try {
$this->dateTimeObject = new DateTime($this->string);
} catch (\Exception $e) {
throw new CouldNotParseDateStringException($e->getMessage());
}

$this->datetime = $this->dateTimeObject->format('c');
$this->sentence = $this->dateTimeObject->format('l M jS, Y, \a\t g:ia');
Expand Down
2 changes: 1 addition & 1 deletion src/Models/MarkdownPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MarkdownPost extends MarkdownDocument
public static string $parserClass = MarkdownPostParser::class;

/**
* @throws \Exception
* @throws \Hyde\Framework\Exceptions\CouldNotParseDateStringException
*/
public function __construct(array $matter, string $body, string $title = '', string $slug = '')
{
Expand Down
15 changes: 8 additions & 7 deletions tests/Feature/Actions/CreatesNewPageSourceFileTest.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<?php

namespace Tests\Feature;
namespace Tests\Feature\Actions;

use Exception;
use Hyde\Framework\Actions\CreatesNewPageSourceFile;
use Hyde\Framework\Exceptions\FileConflictException;
use Hyde\Framework\Exceptions\UnsupportedPageTypeException;
use Hyde\Framework\Hyde;
use Hyde\Framework\Models\BladePage;
use Hyde\Framework\Models\DocumentationPage;
Expand Down Expand Up @@ -45,7 +46,7 @@ public function test_that_a_slug_is_generated_from_the_title()

public function test_that_an_exception_is_thrown_for_invalid_page_type()
{
$this->expectException(Exception::class);
$this->expectException(UnsupportedPageTypeException::class);
$this->expectExceptionMessage('The page type must be either "markdown", "blade", or "documentation"');

(new CreatesNewPageSourceFile('682072b Test Page', 'invalid'));
Expand All @@ -56,8 +57,8 @@ public function test_that_an_exception_is_thrown_if_file_already_exists_and_over
$path = Hyde::path('_pages/foo.md');
file_put_contents($path, 'foo');

$this->expectException(Exception::class);
$this->expectExceptionMessage("File $path already exists!");
$this->expectException(FileConflictException::class);
$this->expectExceptionMessage("File already exists: $path");
$this->expectExceptionCode(409);

new CreatesNewPageSourceFile('foo');
Expand Down Expand Up @@ -131,12 +132,12 @@ public function test_that_the_file_path_can_be_returned()
{
$this->assertEquals(
Hyde::path('_pages/682072b-test-page.md'),
(new CreatesNewPageSourceFile('682072b Test Page'))->path
(new CreatesNewPageSourceFile('682072b Test Page'))->outputPath
);

$this->assertEquals(
Hyde::path('_pages/682072b-test-page.blade.php'),
(new CreatesNewPageSourceFile('682072b Test Page', BladePage::class))->path
(new CreatesNewPageSourceFile('682072b Test Page', BladePage::class))->outputPath
);
}
}
5 changes: 3 additions & 2 deletions tests/Feature/Commands/HydeMakePageCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Tests\Feature\Commands;

use Exception;
use Hyde\Framework\Exceptions\FileConflictException;
use Hyde\Framework\Hyde;
use Tests\TestCase;

Expand Down Expand Up @@ -102,8 +103,8 @@ public function test_command_fails_if_file_already_exists()
{
file_put_contents($this->markdownPath, 'This should not be overwritten');

$this->expectException(Exception::class);
$this->expectExceptionMessage("File $this->markdownPath already exists!");
$this->expectException(FileConflictException::class);
$this->expectExceptionMessage("File already exists: $this->markdownPath");
$this->expectExceptionCode(409);
$this->artisan('make:page "8450de2 test page"')->assertExitCode(409);

Expand Down
Loading