[CORL-144, CORL-143] Nudging (#2236)

* feat: added nudging beheviour to server

* fix: review fixes

* fix: fixed missed change

* fix: fixed sitewide permission error

* feat: implement client side nudging

* test: add feature tests
This commit is contained in:
Wyatt Johnson
2019-03-22 18:09:22 +01:00
committed by Kiwi
parent 647227e66c
commit e70f6f5c7f
27 changed files with 401 additions and 61 deletions
@@ -1,2 +1,3 @@
export { default as UnknownServerError } from "./unknownServerError";
export { default as InvalidRequestError } from "./invalidRequestError";
export { default as ModerationNudgeError } from "./moderationNudgeError";
@@ -14,7 +14,7 @@ interface InvalidRequestExtension {
}
/**
* InvalidRequestError wraps the `BAD_USER_INPUT` error returned from the
* InvalidRequestError wraps the `INVALID_REQUEST_ERROR` error returned from the
* server.
*/
export default class InvalidRequestError extends Error
@@ -0,0 +1,39 @@
import { ERROR_CODES } from "talk-common/errors";
/**
* Shape of the `ModerationNudge` extension as
* the client requires. Note: the only crucial
* field is the `code` field.
*/
interface ModerationNudgeExtension {
code: ERROR_CODES;
message?: string;
id?: string;
}
/**
* ModeratioNudgeError wraps the `MODERATION_NUDGE_ERROR` error returned from the
* server.
*/
export default class ModeratioNudgeError extends Error
implements ModerationNudgeExtension {
// Keep extension of original server response.
public readonly extension: ModerationNudgeExtension;
public readonly code: ERROR_CODES;
public readonly id?: string;
public readonly message: string;
public readonly extensions: string;
constructor(extension: ModerationNudgeExtension) {
super("ModeratioNudgeError");
// Maintains proper stack trace for where our error was thrown.
if (Error.captureStackTrace) {
Error.captureStackTrace(this, ModeratioNudgeError);
}
this.extension = extension;
this.code = extension.code;
this.id = extension.id;
this.message = extension.message || extension.code;
}
}
@@ -1,6 +1,10 @@
import { ERROR_TYPES } from "talk-common/errors";
import { InvalidRequestError, UnknownServerError } from "../errors";
import {
InvalidRequestError,
ModerationNudgeError,
UnknownServerError,
} from "../errors";
export default function extractError(errors: Error[]): Error | null {
if (errors.length > 1 || !(errors[0] as any).extensions) {
@@ -15,5 +19,8 @@ export default function extractError(errors: Error[]): Error | null {
if ((err as any).extensions.type === ERROR_TYPES.INVALID_REQUEST_ERROR) {
return new InvalidRequestError((err as any).extensions);
}
if ((err as any).extensions.type === ERROR_TYPES.MODERATION_NUDGE_ERROR) {
return new ModerationNudgeError((err as any).extensions);
}
return new UnknownServerError(err.message, (err as any).extensions);
}
+1 -1
View File
@@ -27,7 +27,7 @@ const handleResp = async (res: Response) => {
if (!res.ok) {
const response = await res.json();
throw new Error(response.error);
throw new Error(response.error.message);
}
if (res.status === 204) {
@@ -19,7 +19,10 @@ import {
} from "talk-framework/lib/relay";
import { loadSchema } from "talk-common/graphql";
import { InvalidRequestError } from "talk-framework/lib/errors";
import {
InvalidRequestError,
ModerationNudgeError,
} from "talk-framework/lib/errors";
export interface CreateRelayEnvironmentNetworkParams {
/** project name of graphql-config */
@@ -72,7 +75,10 @@ function createFetch({
if (payload.errors) {
payload.errors.forEach(e => {
// Throw our custom errors directly.
if (e.originalError instanceof InvalidRequestError) {
if (
e.originalError instanceof InvalidRequestError ||
e.originalError instanceof ModerationNudgeError
) {
throw e.originalError;
}
});