aboutsummaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2021-08-14 22:28:17 +0200
committerHampusM <hampus@hampusmat.com>2021-08-14 22:28:17 +0200
commitddcf71225226bc0929d5c6d609b13ff0489e5b94 (patch)
tree7f788d29af4441e27d709aaec1359e205871a11b /packages
parent81b39ee7848b0fbdcd8b61a04077a58c23580dd1 (diff)
Revamped backend error handling & improved imports in tests
Diffstat (limited to 'packages')
-rw-r--r--packages/server/src/git/blob.ts4
-rw-r--r--packages/server/src/git/branch.ts8
-rw-r--r--packages/server/src/git/commit.ts10
-rw-r--r--packages/server/src/git/diff.ts4
-rw-r--r--packages/server/src/git/error.ts75
-rw-r--r--packages/server/src/git/error/index.ts60
-rw-r--r--packages/server/src/git/error/types.ts39
-rw-r--r--packages/server/src/git/misc.ts6
-rw-r--r--packages/server/src/git/repository.ts8
-rw-r--r--packages/server/src/git/tag.ts6
-rw-r--r--packages/server/src/git/tree.ts6
-rw-r--r--packages/server/src/routes/api/v1/index.ts6
-rw-r--r--packages/server/src/routes/api/v1/repo/index.ts22
-rw-r--r--packages/server/src/routes/repo.ts10
14 files changed, 144 insertions, 120 deletions
diff --git a/packages/server/src/git/blob.ts b/packages/server/src/git/blob.ts
index 5d1d892..ad88ca5 100644
--- a/packages/server/src/git/blob.ts
+++ b/packages/server/src/git/blob.ts
@@ -1,4 +1,4 @@
-import { BlobError, createError } from "./error";
+import { createError, ErrorWhere, IsNotError } from "./error";
import { Tree } from "./tree";
import { BlobTreeEntry } from "./tree_entry";
@@ -37,7 +37,7 @@ export class Blob {
const entry = await tree.find(path);
if(!(entry instanceof BlobTreeEntry)) {
- throw(createError(BlobError, 500, "Not a blob"));
+ throw(createError(ErrorWhere.Blob, IsNotError, "tree entry", "a blob"));
}
return new Blob(entry);
diff --git a/packages/server/src/git/branch.ts b/packages/server/src/git/branch.ts
index 1dbb690..dacabda 100644
--- a/packages/server/src/git/branch.ts
+++ b/packages/server/src/git/branch.ts
@@ -2,7 +2,7 @@ import { CommitSummary } from "./commit";
import { Reference } from "./reference";
import { Repository } from "./repository";
import { Repository as NodeGitRepository } from "nodegit";
-import { BranchError, createError } from "./error";
+import { createError, ErrorWhere, FailedError, NotFoundError, UnknownError } from "./error";
/**
* A representation of a branch
@@ -17,7 +17,7 @@ export class Branch extends Reference {
*/
public async latestCommit(): Promise<CommitSummary> {
const latest_commit = this._owner.ng_repository.getBranchCommit(this._ng_reference).catch(() => {
- throw(createError(BranchError, 500, "Failed to get the latest commit"));
+ throw(createError(ErrorWhere.Branch, FailedError, "get the latest commit"));
});
return {
@@ -37,9 +37,9 @@ export class Branch extends Reference {
public static async lookup(owner: Repository, branch: string): Promise<Branch> {
const reference = await owner.ng_repository.getBranch(branch).catch(err => {
if(err.errno === -3) {
- throw(createError(BranchError, 404, "Branch not found!"));
+ throw(createError(ErrorWhere.Branch, NotFoundError, "branch"));
}
- throw(createError(BranchError, 500, "Something went wrong."));
+ throw(createError(ErrorWhere.Branch, UnknownError));
});
return new Branch(owner, reference);
}
diff --git a/packages/server/src/git/commit.ts b/packages/server/src/git/commit.ts
index 32b5869..d5d8eab 100644
--- a/packages/server/src/git/commit.ts
+++ b/packages/server/src/git/commit.ts
@@ -7,7 +7,7 @@ import { createMessage, readKey, readSignature, verify } from "openpgp";
import { promisify } from "util";
import { exec } from "child_process";
import { findAsync } from "./misc";
-import { CommitError, createError } from "./error";
+import { ErrorWhere, createError, CommitNotSignedError, FailedError } from "./error";
const pExec = promisify(exec);
@@ -46,7 +46,7 @@ export class CommitAuthor implements Author {
*/
public async fingerprint(): Promise<string> {
const basic_signature = await this._ng_commit.getSignature().catch(() => {
- throw(createError(CommitError, 500, "Commit isn't signed!"));
+ throw(createError(ErrorWhere.Commit, CommitNotSignedError));
});
const message = await createMessage({ text: basic_signature.signedData });
@@ -54,7 +54,7 @@ export class CommitAuthor implements Author {
const pub_keys_list = await pExec("gpg --list-public-keys");
if(pub_keys_list.stderr) {
- throw(createError(CommitError, 500, "Failed to get public keys from gpg!"));
+ throw(createError(ErrorWhere.Commit, FailedError, "get public keys from gpg!"));
}
const pub_keys = pub_keys_list.stdout
@@ -79,7 +79,7 @@ export class CommitAuthor implements Author {
const key_export = await pExec(`gpg --armor --export ${fingerprint}`);
if(key_export.stderr) {
- throw(createError(CommitError, 500, "Failed to export a public key from gpg!"));
+ throw(createError(ErrorWhere.Commit, FailedError, "export a public key from gpg!"));
}
const signature = await readSignature({ armoredSignature: basic_signature.signature });
@@ -97,7 +97,7 @@ export class CommitAuthor implements Author {
});
if(!pub_key) {
- throw(createError(CommitError, 500, "Failed to find a public key matching the commit signature!"));
+ throw(createError(ErrorWhere.Commit, FailedError, "find a public key matching the commit signature!"));
}
return pub_key
diff --git a/packages/server/src/git/diff.ts b/packages/server/src/git/diff.ts
index 3d69183..d084e5d 100644
--- a/packages/server/src/git/diff.ts
+++ b/packages/server/src/git/diff.ts
@@ -1,5 +1,5 @@
import { Diff as NodeGitDiff } from "nodegit";
-import { createError, DiffError } from "./error";
+import { createError, ErrorWhere, NotFoundError } from "./error";
import { Patch } from "./patch";
type PatchHeaderData = {
@@ -75,7 +75,7 @@ export class Diff {
const patch = (await this.ng_diff.patches())[index];
if(!patch) {
- throw(createError(DiffError, 500, "Patch not found"));
+ throw(createError(ErrorWhere.Diff, NotFoundError, "Patch"));
}
return new Patch(this, (await this.ng_diff.patches())[index], index);
diff --git a/packages/server/src/git/error.ts b/packages/server/src/git/error.ts
deleted file mode 100644
index b89b994..0000000
--- a/packages/server/src/git/error.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-export abstract class BaseError implements Error {
- code: number;
- name: string;
- message: string;
- stack?: string | undefined;
-
- constructor(code: number, message: string) {
- this.name = "Githermit Error";
-
- this.code = code;
- this.message = message;
- }
-}
-
-export class RepositoryError extends BaseError {
- constructor(code: number, message: string) {
- super(code, "A repository error has occured: " + message);
- }
-}
-
-export class BranchError extends BaseError {
- constructor(code: number, message: string) {
- super(code, "A branch error has occured: " + message);
- }
-}
-
-export class TagError extends BaseError {
- constructor(code: number, message: string) {
- super(code, "A tag error has occured: " + message);
- }
-}
-
-export class TreeError extends BaseError {
- constructor(code: number, message: string) {
- super(code, "A tree error has occured: " + message);
- }
-}
-
-export class BlobError extends BaseError {
- constructor(code: number, message: string) {
- super(code, "A blob error has occured: " + message);
- }
-}
-
-export class MiscError extends BaseError {
- constructor(code: number, message: string) {
- super(code, "A misc error has occured: " + message);
- }
-}
-
-export class DiffError extends BaseError {
- constructor(code: number, message: string) {
- super(code, "A diff error has occured: " + message);
- }
-}
-
-export class CommitError extends BaseError {
- constructor(code: number, message: string) {
- super(code, "A commit error has occured: " + message);
- }
-}
-
-type ErrorConstructorType<T> = new (code: number, message: string) => T;
-
-/**
- * An error factory
- *
- * @param ErrorConstructor - The constructor for what error to create
- * @param code - A HTTP code
- * @param message - A error message
- * @returns An instance of a error
- */
-export function createError<E extends BaseError>(ErrorConstructor: ErrorConstructorType<E>, code: number, message: string): E {
- return new ErrorConstructor(code, message);
-} \ No newline at end of file
diff --git a/packages/server/src/git/error/index.ts b/packages/server/src/git/error/index.ts
new file mode 100644
index 0000000..b8994d3
--- /dev/null
+++ b/packages/server/src/git/error/index.ts
@@ -0,0 +1,60 @@
+import { ErrorType } from "./types";
+
+export * from "./types";
+
+export class ServerError extends Error {
+ code: number;
+
+ constructor(where: string, error_type: { code: number, message: string }) {
+ super(`A ${where} error has occured: ${error_type.message}`);
+
+ this.name = "Server Error";
+ this.code = error_type.code;
+ }
+}
+
+export enum ErrorWhere {
+ Repository = "repository",
+ Tree = "tree",
+ Tag = "tag",
+ Branch = "branch",
+ Commit = "commit",
+ Diff = "diff",
+ Misc = "misc",
+ Blob = "blob"
+}
+
+/**
+ * A error factory
+ *
+ * @param where - Where the error has occured
+ * @param err_type - What type of error it is
+ * @param args - Parameters for the error type
+ *
+ * @returns A server error
+ *
+ * @example Example usage:
+ * import { ErrorType, NotFoundError, createError } from "./error";
+ *
+ * throw(createError(ErrorType.Repository, NotFoundError, "chili sauce"));
+ */
+export function createError<T extends new (...args: string[]) => ErrorType>(where: ErrorWhere, ErrType: T, ...args: ConstructorParameters<T>): ServerError;
+
+/**
+ * A error factory
+ *
+ * @param where - Where the error has occured
+ * @param err_type - What type of error it is
+ *
+ * @returns A server error
+ *
+ * @example Example usage:
+ * import { ErrorType, UnknownError, createError } from "./error";
+ *
+ * throw(createError(ErrorType.Repository, UnknownError));
+ */
+export function createError<T extends new () => ErrorType>(where: ErrorWhere, ErrType: T): ServerError;
+
+export function createError<T extends new(...args: string[]) => ErrorType>(where: ErrorWhere, ErrType: T, ...args: ConstructorParameters<T>): ServerError {
+ return new ServerError(where, new ErrType(...args));
+} \ No newline at end of file
diff --git a/packages/server/src/git/error/types.ts b/packages/server/src/git/error/types.ts
new file mode 100644
index 0000000..b8f2de7
--- /dev/null
+++ b/packages/server/src/git/error/types.ts
@@ -0,0 +1,39 @@
+export abstract class ErrorType {
+ code: number;
+ message: string;
+
+ constructor(code: number, message: string) {
+ this.code = code;
+ this.message = message;
+ }
+}
+
+export class UnknownError extends ErrorType {
+ constructor() {
+ super(500, "Unknown error!");
+ }
+}
+
+export class NotFoundError extends ErrorType {
+ constructor(target: string) {
+ super(404, `${target} not found!`);
+ }
+}
+
+export class FailedError extends ErrorType {
+ constructor(attempt: string) {
+ super(500, `Failed to ${attempt}!`);
+ }
+}
+
+export class IsNotError extends ErrorType {
+ constructor(target: string, not: string) {
+ super(500, `${target} is not a ${not}!`);
+ }
+}
+
+export class CommitNotSignedError extends ErrorType {
+ constructor() {
+ super(500, "Commit isn't signed!");
+ }
+} \ No newline at end of file
diff --git a/packages/server/src/git/misc.ts b/packages/server/src/git/misc.ts
index 1fda304..43c7a70 100644
--- a/packages/server/src/git/misc.ts
+++ b/packages/server/src/git/misc.ts
@@ -1,5 +1,5 @@
import { readFile, readdir } from "fs";
-import { createError, MiscError } from "./error";
+import { createError, ErrorWhere, FailedError } from "./error";
/**
* Asynchronously find an item in an array that matches the requirements set by the callback
@@ -25,7 +25,7 @@ export function getFile(git_dir: string, repository: string, file: string): Prom
return new Promise((resolve, reject) => {
readFile(`${git_dir}/${repository}/${file}`, (err, content) => {
if(err) {
- reject(createError(MiscError, 500, "Failed to open repository file " + file));
+ reject(createError(ErrorWhere.Misc, FailedError, `open repository file '${file}'`));
return;
}
@@ -44,7 +44,7 @@ export function getDirectory(directory: string): Promise<string[]> {
return new Promise<string[]>((resolve, reject) => {
readdir(directory, (err, dir_content) => {
if(err) {
- reject(createError(MiscError, 500, "Failed to open directory " + directory));
+ reject(createError(ErrorWhere.Misc, FailedError, `open directory '${directory}'`));
return;
}
diff --git a/packages/server/src/git/repository.ts b/packages/server/src/git/repository.ts
index 63ede23..9e83281 100644
--- a/packages/server/src/git/repository.ts
+++ b/packages/server/src/git/repository.ts
@@ -7,7 +7,7 @@ import { Commit } from "./commit";
import { FastifyReply } from "fastify";
import { Tag } from "./tag";
import { Tree } from "./tree";
-import { createError, RepositoryError } from "./error";
+import { createError, ErrorWhere, NotFoundError, UnknownError } from "./error";
/**
* Returns the full name of a git repository
@@ -162,15 +162,15 @@ export class Repository {
public static async open(git_dir: string, repository: string, branch?: string): Promise<Repository> {
let ng_repository = await NodeGitRepository.openBare(`${git_dir}/${getFullRepositoryName(repository)}`).catch((err: WeirdError) => {
if(err.errno === -3) {
- throw(createError(RepositoryError, 404, "Repository not found"));
+ throw(createError(ErrorWhere.Repository, NotFoundError, "repository"));
}
- throw(createError(RepositoryError, 500, "Unknown error"));
+ throw(createError(ErrorWhere.Repository, UnknownError));
});
if(branch) {
if(!await Branch.lookupExists(ng_repository, branch)) {
- throw(createError(RepositoryError, 404, "Branch not found!"));
+ throw(createError(ErrorWhere.Repository, NotFoundError, "branch"));
}
}
diff --git a/packages/server/src/git/tag.ts b/packages/server/src/git/tag.ts
index b792516..6c61a65 100644
--- a/packages/server/src/git/tag.ts
+++ b/packages/server/src/git/tag.ts
@@ -5,7 +5,7 @@ import { Reference } from "./reference";
import { Repository } from "./repository";
import { createGzip } from "zlib";
import { pipeline } from "stream";
-import { createError, TagError } from "./error";
+import { createError, ErrorWhere, FailedError, NotFoundError } from "./error";
import { Author } from "../../../api/src";
import { promisify } from "util";
@@ -88,10 +88,10 @@ export class Tag extends Reference {
public static async lookup(owner: Repository, tag: string): Promise<Tag> {
const reference = await owner.ng_repository.getReference(tag).catch(err => {
if(err.errno === -3) {
- throw(createError(TagError, 404, "Tag not found"));
+ throw(createError(ErrorWhere.Tag, NotFoundError, "Tag"));
}
- throw(createError(TagError, 404, "Failed to get tag"));
+ throw(createError(ErrorWhere.Tag, FailedError, "get tag"));
});
return new Tag(owner, reference);
diff --git a/packages/server/src/git/tree.ts b/packages/server/src/git/tree.ts
index 7936e5d..4b6d329 100644
--- a/packages/server/src/git/tree.ts
+++ b/packages/server/src/git/tree.ts
@@ -1,7 +1,7 @@
import { Tree as NodeGitTree } from "nodegit";
import { Repository } from "./repository";
import { BaseTreeEntry, BlobTreeEntry, createTreeEntry, TreeEntry } from "./tree_entry";
-import { createError, TreeError } from "./error";
+import { createError, ErrorWhere, FailedError, NotFoundError } from "./error";
import { pack, Pack } from "tar-stream";
import { Commit } from "./commit";
@@ -42,9 +42,9 @@ export class Tree {
public async find(path: string): Promise<BaseTreeEntry> {
const entry = await this._ng_tree.getEntry(path).catch(err => {
if(err.errno === -3) {
- throw(createError(TreeError, 404, `Path '${path}' not found`));
+ throw(createError(ErrorWhere.Tree, NotFoundError, `Path '${path}'`));
}
- throw(createError(TreeError, 500, "Failed to get tree path"));
+ throw(createError(ErrorWhere.Tree, FailedError, "get tree path"));
});
return createTreeEntry(this._owner, entry);
diff --git a/packages/server/src/routes/api/v1/index.ts b/packages/server/src/routes/api/v1/index.ts
index 1adb3cb..fa7d8ab 100644
--- a/packages/server/src/routes/api/v1/index.ts
+++ b/packages/server/src/routes/api/v1/index.ts
@@ -4,7 +4,7 @@ import { Route } from "../../../types/fastify";
import repo from "./repo";
import { verifyRepoName } from "../util";
import { Info as APIInfo, RepositorySummary as APIRepositorySummary, Repository as APIRepository } from "api";
-import { BaseError } from "../../../git/error";
+import { ServerError } from "../../../git/error";
function setHandlers(fastify: FastifyInstance): void {
fastify.setErrorHandler((err, req, reply) => {
@@ -49,9 +49,9 @@ function reposEndpoints(fastify: FastifyInstance, opts: FastifyPluginOptions, do
return;
}
- const repository: Repository | BaseError = await Repository.open(opts.config.settings.git_dir, req.params.repo).catch(err => err);
+ const repository = await Repository.open(opts.config.settings.git_dir, req.params.repo).catch((err: ServerError) => err);
- if(repository instanceof BaseError) {
+ if(repository instanceof ServerError) {
reply.code(repository.code).send({ error: repository.message });
return;
}
diff --git a/packages/server/src/routes/api/v1/repo/index.ts b/packages/server/src/routes/api/v1/repo/index.ts
index bcd2e5c..059a9d4 100644
--- a/packages/server/src/routes/api/v1/repo/index.ts
+++ b/packages/server/src/routes/api/v1/repo/index.ts
@@ -8,7 +8,7 @@ import branches from "./branches";
import log from "./log";
import { verifyRepoName } from "../../util";
import { Tree as APITree, Tag as APITag, TreeEntry as APITreeEntry } from "api";
-import { BaseError } from "../../../../git/error";
+import { ServerError } from "../../../../git/error";
import { commitMap } from "./map";
declare module "fastify" {
@@ -19,9 +19,9 @@ declare module "fastify" {
function addHooks(fastify: FastifyInstance, opts: FastifyPluginOptions): void {
fastify.addHook("preHandler", async(req: CoolFastifyRequest, reply) => {
- const repository = await Repository.open(opts.config.settings.git_dir, req.params.repo, req.query.branch).catch((err: BaseError) => err);
+ const repository = await Repository.open(opts.config.settings.git_dir, req.params.repo, req.query.branch).catch((err: ServerError) => err);
- if(repository instanceof BaseError) {
+ if(repository instanceof ServerError) {
reply.code(repository.code).send({ error: repository.message });
return;
}
@@ -67,9 +67,9 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
method: "GET",
url: "/tree",
handler: async(req, reply) => {
- const tree = await req.repository.tree().catch((err: BaseError) => err);
+ const tree = await req.repository.tree().catch((err: ServerError) => err);
- if(tree instanceof BaseError) {
+ if(tree instanceof ServerError) {
reply.code(tree.code).send({ error: tree.message });
return;
}
@@ -81,9 +81,9 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
let data: APITree;
if(tree_path) {
- const tree_path_entry = await tree.find(tree_path).catch((err: BaseError) => err);
+ const tree_path_entry = await tree.find(tree_path).catch((err: ServerError) => err);
- if(tree_path_entry instanceof BaseError) {
+ if(tree_path_entry instanceof ServerError) {
reply.code(tree_path_entry.code).send({ error: tree_path_entry.message });
return;
}
@@ -104,9 +104,9 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
method: "GET",
url: "/tree/history",
handler: async(req, reply) => {
- const tree = await req.repository.tree().catch((err: BaseError) => err);
+ const tree = await req.repository.tree().catch((err: ServerError) => err);
- if(tree instanceof BaseError) {
+ if(tree instanceof ServerError) {
reply.code(tree.code).send({ error: tree.message });
return;
}
@@ -118,9 +118,9 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
const tree_path = req.query.path;
- const tree_entry = await tree.find(tree_path).catch((err: BaseError) => err);
+ const tree_entry = await tree.find(tree_path).catch((err: ServerError) => err);
- if(tree_entry instanceof BaseError) {
+ if(tree_entry instanceof ServerError) {
reply.code(tree_entry.code).send({ error: tree_entry.message });
return;
}
diff --git a/packages/server/src/routes/repo.ts b/packages/server/src/routes/repo.ts
index 43d89d2..32ac9c4 100644
--- a/packages/server/src/routes/repo.ts
+++ b/packages/server/src/routes/repo.ts
@@ -3,7 +3,7 @@ import { CoolFastifyRequest, Route } from "../types/fastify";
import { Tag } from "../git/tag";
import { FastifyInstance, FastifyPluginOptions } from "fastify";
import { verifyRepoName } from "../routes/api/util";
-import { BaseError } from "../git/error";
+import { ServerError } from "../git/error";
export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error) => void): void {
fastify.addHook("onRequest", async(req: CoolFastifyRequest, reply) => {
@@ -62,16 +62,16 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
method: "GET",
url: "/refs/tags/:tag",
handler: async(req, reply) => {
- const repository = await Repository.open(opts.config.settings.git_dir, req.params.repo).catch((err: BaseError) => err);
+ const repository = await Repository.open(opts.config.settings.git_dir, req.params.repo).catch((err: ServerError) => err);
- if(repository instanceof BaseError) {
+ if(repository instanceof ServerError) {
reply.code(repository.code).send(repository.message);
return;
}
- const tag = await Tag.lookup(repository, req.params.tag).catch((err: BaseError) => err);
+ const tag = await Tag.lookup(repository, req.params.tag).catch((err: ServerError) => err);
- if(tag instanceof BaseError) {
+ if(tag instanceof ServerError) {
reply.code(tag.code).send(tag.message);
return;
}