Skip to content

Commit 784a990

Browse files
authored
Merge pull request #454 from hydephp/450-add-custom-exceptions
Fix #450: Add custom exceptions
2 parents 05dd3d2 + 24af0aa commit 784a990

15 files changed

+151
-84
lines changed

src/Actions/CreatesNewMarkdownPostFile.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Hyde\Framework\Actions;
44

5-
use Exception;
5+
use Hyde\Framework\Exceptions\FileConflictException;
66
use Hyde\Framework\Hyde;
77
use Illuminate\Support\Str;
88

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

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

108108
$arrayWithoutSlug = ((array) $this);

src/Actions/CreatesNewPageSourceFile.php

+14-62
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
namespace Hyde\Framework\Actions;
44

5-
use Exception;
5+
use Hyde\Framework\Exceptions\FileConflictException;
6+
use Hyde\Framework\Exceptions\UnsupportedPageTypeException;
67
use Hyde\Framework\Hyde;
78
use Hyde\Framework\Models\BladePage;
89
use Hyde\Framework\Models\DocumentationPage;
@@ -16,32 +17,10 @@
1617
*/
1718
class CreatesNewPageSourceFile
1819
{
19-
/**
20-
* The Page title.
21-
*
22-
* @var string
23-
*/
2420
public string $title;
25-
26-
/**
27-
* The Page slug.
28-
*/
2921
public string $slug;
22+
public string $outputPath;
3023

31-
/**
32-
* The file path.
33-
*/
34-
public string $path;
35-
36-
/**
37-
* Construct the class.
38-
*
39-
* @param string $title - The page title, will be used to generate the slug
40-
* @param string $type - The page type, FQDN of the page class
41-
* @param bool $force - Overwrite any existing files?
42-
*
43-
* @throws Exception if the page type is not supported or the file already exists
44-
*/
4524
public function __construct(string $title, string $type = MarkdownPage::class, public bool $force = false)
4625
{
4726
$this->title = $title;
@@ -50,25 +29,13 @@ public function __construct(string $title, string $type = MarkdownPage::class, p
5029
$this->createPage($type);
5130
}
5231

53-
/**
54-
* Check if the file can be saved.
55-
*
56-
* @throws Exception if the file already exists and cannot be overwritten
57-
*/
5832
public function canSaveFile(string $path): void
5933
{
6034
if (file_exists($path) && ! $this->force) {
61-
throw new Exception("File $path already exists!", 409);
35+
throw new FileConflictException($path);
6236
}
6337
}
6438

65-
/**
66-
* Create the page.
67-
*
68-
* @param string $type FQDN of the page class
69-
*
70-
* @throws Exception if the page type is not supported
71-
*/
7239
public function createPage(string $type): int|false
7340
{
7441
if ($type === MarkdownPage::class) {
@@ -82,39 +49,29 @@ public function createPage(string $type): int|false
8249
return $this->createDocumentationFile();
8350
}
8451

85-
throw new Exception('The page type must be either "markdown", "blade", or "documentation"');
52+
throw new UnsupportedPageTypeException('The page type must be either "markdown", "blade", or "documentation"');
8653
}
8754

88-
/**
89-
* Create the Markdown file.
90-
*
91-
* @throws Exception if the file cannot be saved.
92-
*/
9355
public function createMarkdownFile(): int|false
9456
{
95-
$this->path = Hyde::path("_pages/$this->slug.md");
57+
$this->outputPath = Hyde::path("_pages/$this->slug.md");
9658

97-
$this->canSaveFile($this->path);
59+
$this->canSaveFile($this->outputPath);
9860

9961
return file_put_contents(
100-
$this->path,
62+
$this->outputPath,
10163
"---\ntitle: $this->title\n---\n\n# $this->title\n"
10264
);
10365
}
10466

105-
/**
106-
* Create the Blade file.
107-
*
108-
* @throws Exception if the file cannot be saved.
109-
*/
11067
public function createBladeFile(): int|false
11168
{
112-
$this->path = Hyde::path("_pages/$this->slug.blade.php");
69+
$this->outputPath = Hyde::path("_pages/$this->slug.blade.php");
11370

114-
$this->canSaveFile($this->path);
71+
$this->canSaveFile($this->outputPath);
11572

11673
return file_put_contents(
117-
$this->path,
74+
$this->outputPath,
11875
<<<EOF
11976
@extends('hyde::layouts.app')
12077
@section('content')
@@ -130,19 +87,14 @@ public function createBladeFile(): int|false
13087
);
13188
}
13289

133-
/**
134-
* Create the Documentation file.
135-
*
136-
* @throws Exception if the file cannot be saved.
137-
*/
13890
public function createDocumentationFile(): int|false
13991
{
140-
$this->path = Hyde::path("_docs/$this->slug.md");
92+
$this->outputPath = Hyde::path("_docs/$this->slug.md");
14193

142-
$this->canSaveFile($this->path);
94+
$this->canSaveFile($this->outputPath);
14395

14496
return file_put_contents(
145-
$this->path,
97+
$this->outputPath,
14698
"# $this->title\n"
14799
);
148100
}

src/Concerns/HasDateString.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ trait HasDateString
1414
public ?DateString $date = null;
1515

1616
/**
17-
* @throws \Exception
17+
* @throws \Hyde\Framework\Exceptions\CouldNotParseDateStringException
1818
*/
1919
public function constructDateString(): void
2020
{

src/Concerns/ValidatesExistence.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@
22

33
namespace Hyde\Framework\Concerns;
44

5-
use Exception;
5+
use Hyde\Framework\Exceptions\FileNotFoundException;
66
use Hyde\Framework\Hyde;
77

88
/**
99
* Validate the existence of a Page model's source file.
10+
*
11+
* @see \Tests\Unit\ValidatesExistenceTest
1012
*/
1113
trait ValidatesExistence
1214
{
1315
/**
1416
* Check if a supplied source file exists or throw an exception.
1517
*
16-
* @throws Exception If the file does not exist.
18+
* @throws FileNotFoundException If the file does not exist.
1719
*/
1820
public function validateExistence(string $model, string $slug): void
1921
{
@@ -22,7 +24,7 @@ public function validateExistence(string $model, string $slug): void
2224
$slug.$model::$fileExtension;
2325

2426
if (! file_exists(Hyde::path($filepath))) {
25-
throw new Exception("File $filepath not found.", 404);
27+
throw new FileNotFoundException($filepath);
2628
}
2729
}
2830
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Hyde\Framework\Exceptions;
4+
5+
use Exception;
6+
7+
class CouldNotParseDateStringException extends Exception
8+
{
9+
//
10+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Hyde\Framework\Exceptions;
4+
5+
use Exception;
6+
7+
class FileConflictException extends Exception
8+
{
9+
protected $message = 'A file already exists at this path.';
10+
protected $code = 409;
11+
12+
public function __construct(?string $path = null)
13+
{
14+
$this->message = $path ? "File already exists: {$path}" : $this->message;
15+
}
16+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Hyde\Framework\Exceptions;
4+
5+
use Exception;
6+
7+
class FileNotFoundException extends Exception
8+
{
9+
protected $message = 'File not found.';
10+
protected $code = 404;
11+
12+
public function __construct(?string $path = null)
13+
{
14+
$this->message = $path ? "File not found: {$path}" : $this->message;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Hyde\Framework\Exceptions;
4+
5+
use Exception;
6+
7+
class UnsupportedPageTypeException extends Exception
8+
{
9+
protected $message = 'The page type is not supported.';
10+
protected $code = 400;
11+
12+
public function __construct(?string $page = null)
13+
{
14+
$this->message = $page ? "The page type is not supported: {$page}" : $this->message;
15+
}
16+
}

src/Hyde.php

-3
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ public static function titleFromSlug(string $slug): string
5353
return Str::title(str_replace('-', ' ', ($slug)));
5454
}
5555

56-
/**
57-
* @throws \Exception
58-
*/
5956
public static function getLatestPosts(): Collection
6057
{
6158
$collection = new Collection();

src/Models/DateString.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
namespace Hyde\Framework\Models;
44

55
use DateTime;
6+
use Hyde\Framework\Exceptions\CouldNotParseDateStringException;
67

78
/**
89
* Parse a date string and create normalized formats.
10+
*
11+
* @see \Tests\Unit\DateStringTest
912
*/
1013
class DateString
1114
{
@@ -27,13 +30,17 @@ class DateString
2730
/**
2831
* @param string $string
2932
*
30-
* @throws \Exception
33+
* @throws \Hyde\Framework\Exceptions\CouldNotParseDateStringException
3134
*/
3235
public function __construct(string $string)
3336
{
3437
$this->string = $string;
3538

36-
$this->dateTimeObject = new DateTime($this->string);
39+
try {
40+
$this->dateTimeObject = new DateTime($this->string);
41+
} catch (\Exception $e) {
42+
throw new CouldNotParseDateStringException($e->getMessage());
43+
}
3744

3845
$this->datetime = $this->dateTimeObject->format('c');
3946
$this->sentence = $this->dateTimeObject->format('l M jS, Y, \a\t g:ia');

src/Models/MarkdownPost.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class MarkdownPost extends MarkdownDocument
2222
public static string $parserClass = MarkdownPostParser::class;
2323

2424
/**
25-
* @throws \Exception
25+
* @throws \Hyde\Framework\Exceptions\CouldNotParseDateStringException
2626
*/
2727
public function __construct(array $matter, string $body, string $title = '', string $slug = '')
2828
{

tests/Feature/Actions/CreatesNewPageSourceFileTest.php

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
<?php
22

3-
namespace Tests\Feature;
3+
namespace Tests\Feature\Actions;
44

5-
use Exception;
65
use Hyde\Framework\Actions\CreatesNewPageSourceFile;
6+
use Hyde\Framework\Exceptions\FileConflictException;
7+
use Hyde\Framework\Exceptions\UnsupportedPageTypeException;
78
use Hyde\Framework\Hyde;
89
use Hyde\Framework\Models\BladePage;
910
use Hyde\Framework\Models\DocumentationPage;
@@ -45,7 +46,7 @@ public function test_that_a_slug_is_generated_from_the_title()
4546

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

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

59-
$this->expectException(Exception::class);
60-
$this->expectExceptionMessage("File $path already exists!");
60+
$this->expectException(FileConflictException::class);
61+
$this->expectExceptionMessage("File already exists: $path");
6162
$this->expectExceptionCode(409);
6263

6364
new CreatesNewPageSourceFile('foo');
@@ -131,12 +132,12 @@ public function test_that_the_file_path_can_be_returned()
131132
{
132133
$this->assertEquals(
133134
Hyde::path('_pages/682072b-test-page.md'),
134-
(new CreatesNewPageSourceFile('682072b Test Page'))->path
135+
(new CreatesNewPageSourceFile('682072b Test Page'))->outputPath
135136
);
136137

137138
$this->assertEquals(
138139
Hyde::path('_pages/682072b-test-page.blade.php'),
139-
(new CreatesNewPageSourceFile('682072b Test Page', BladePage::class))->path
140+
(new CreatesNewPageSourceFile('682072b Test Page', BladePage::class))->outputPath
140141
);
141142
}
142143
}

tests/Feature/Commands/HydeMakePageCommandTest.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Tests\Feature\Commands;
44

55
use Exception;
6+
use Hyde\Framework\Exceptions\FileConflictException;
67
use Hyde\Framework\Hyde;
78
use Tests\TestCase;
89

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

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

0 commit comments

Comments
 (0)