express#ErrorRequestHandler TypeScript Examples

The following examples show how to use express#ErrorRequestHandler. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: handler.ts    From NLW-3.0 with MIT License 6 votes vote down vote up
errorHandler: ErrorRequestHandler = (error, request, response, next) => {
	if (error instanceof ValidationError) {
		let errors: ValidationErrors = {};

		error.inner.forEach(err => {
			errors[err.path] = err.errors;
		})

		return response.status(400).json({ message: 'Validation fails', errors });
	}

	console.error(error);

	return response.status(500).json({ message: 'Internal server error' });
}
Example #2
Source File: handler.ts    From happy with MIT License 6 votes vote down vote up
errorHandler: ErrorRequestHandler = (error, request, response, next) => {
  if (error instanceof ValidationError) {
    let errors: ValidationErrors = {};

    error.inner.forEach(err => {
      errors[err.path] = err.errors;
    })

    return response.status(400).json({ message: 'Validation fails', errors });
  }

  console.error(error);

  return response.status(500).json({ message: 'Internal Server Error' });
}
Example #3
Source File: server.ts    From GiveNGo with MIT License 6 votes vote down vote up
// Global Error handler
app.use(
  (
    err: ErrorRequestHandler,
    req: Request,
    res: Response,
    next: NextFunction
  ) => {
    // Set up default error
    const defaultError = {
      log: 'Error caught in global error handler',
      status: 500,
      msg: {
        err: err,
      },
    };

    // Update default error message with provided error if there is one
    const output = Object.assign(defaultError, err);
    res.send(output);
  }
);
Example #4
Source File: handle-error.ts    From Discord-Bot-TypeScript-Template with MIT License 6 votes vote down vote up
export function handleError(): ErrorRequestHandler {
    return (error, req, res, _next) => {
        Logger.error(
            Logs.error.apiRequest
                .replaceAll('{HTTP_METHOD}', req.method)
                .replaceAll('{URL}', req.url),
            error
        );
        res.status(500).json({ error: true, message: error.message });
    };
}
Example #5
Source File: server.ts    From express-zod-api with MIT License 6 votes vote down vote up
createParserFailureHandler =
  (errorHandler: AnyResultHandler, logger: Logger): ErrorRequestHandler =>
  (error, request, response, next) => {
    if (!error) {
      return next();
    }
    errorHandler.handler({
      error,
      request,
      response,
      logger,
      input: request.body,
      output: null,
    });
  }
Example #6
Source File: handler.ts    From NextLevelWeek with MIT License 6 votes vote down vote up
errorHandler: ErrorRequestHandler = (error, req, res, next) => {
    if (error instanceof ValidationError) {
        let errors: ValidationErrors = {}

        error.inner.forEach(err => {
            errors[err.path] = err.errors;
        });

        return res.status(400).json({ message: 'Validation fails.', errors });
    }

    console.error(error);

    return res.status(500).json({ message: 'Internal server error.' });
}
Example #7
Source File: app.ts    From commercetools-sdk-typescript with MIT License 6 votes vote down vote up
// Global error handler
app.use(
  (
    error: ErrorRequestHandler,
    req: Request,
    res: Response,
    next: NextFunction
  ) => {
    // response to user with 403 error and details
    if (error) {
      next(error)
    } else {
      next()
    }
  }
)
Example #8
Source File: errorHandler.ts    From livepeer-com with MIT License 6 votes vote down vote up
export default function errorHandler(): ErrorRequestHandler {
  return (err, _req, res, _next) => {
    // If we throw any errors with numerical statuses, use them.
    if (isAPIError(err)) {
      res.status(err.status);
      return res.json({ errors: [err.message] });
    }
    res.status(500);
    console.error(err);
    return res.json({ errors: [err.stack] });
  };
}
Example #9
Source File: handler.ts    From happy with MIT License 6 votes vote down vote up
errorHandler: ErrorRequestHandler = (error, req, res, next) => {

  if (error instanceof ValidationError) {
    let errors: ValidationErrors = {}

    error.inner.forEach(err => {
      errors[err.path] = err.errors;
    });

    return res.status(400).json({ message: "Validation fails", errors })
  }

  console.error(error);

  return res.status(500).json({ message: "Internal server error" });
}
Example #10
Source File: server.ts    From DockerLocal with MIT License 6 votes vote down vote up
// Global Error handler
app.use(
  (
    err: ErrorRequestHandler,
    req: Request,
    res: Response,
    next: NextFunction
  ) => {
    // Set up default error
    const defaultError = {
      log: "Error caught in global error handler",
      status: 500,
      msg: {
        err,
      },
    };

    // Update default error message with provided error if there is one
    const output = Object.assign(defaultError, err);
    console.log(output.log);
    res.send(output.msg);
  }
);
Example #11
Source File: handler.ts    From nlw-03-omnistack with MIT License 6 votes vote down vote up
errorHandler: ErrorRequestHandler = (error, request, response, next) => {
  if (error instanceof ValidationError) {
    let errors: ValidationErrors = {};

    error.inner.forEach(err => {
      errors[err.path] = err.errors;
    });

    return response.status(400).json({ message: 'Validation fails.', errors });
  }

  console.error(error);

  return response.status(500).json({ message: 'Internal server error.' });
}
Example #12
Source File: errorHandler.ts    From backstage with Apache License 2.0 5 votes vote down vote up
/**
 * Express middleware to handle errors during request processing.
 *
 * This is commonly the very last middleware in the chain.
 *
 * Its primary purpose is not to do translation of business logic exceptions,
 * but rather to be a global catch-all for uncaught "fatal" errors that are
 * expected to result in a 500 error. However, it also does handle some common
 * error types (such as http-error exceptions) and returns the enclosed status
 * code accordingly.
 *
 * @public
 * @returns An Express error request handler
 */
export function errorHandler(
  options: ErrorHandlerOptions = {},
): ErrorRequestHandler {
  const showStackTraces =
    options.showStackTraces ?? process.env.NODE_ENV === 'development';

  const logger = (options.logger || getRootLogger()).child({
    type: 'errorHandler',
  });

  return (error: Error, req: Request, res: Response, next: NextFunction) => {
    const statusCode = getStatusCode(error);
    if (options.logClientErrors || statusCode >= 500) {
      logger.error(error);
    }

    if (res.headersSent) {
      // If the headers have already been sent, do not send the response again
      // as this will throw an error in the backend.
      next(error);
      return;
    }

    const body: ErrorResponseBody = {
      error: serializeError(error, { includeStack: showStackTraces }),
      request: { method: req.method, url: req.url },
      response: { statusCode },
    };

    res.status(statusCode).json(body);
  };
}
Example #13
Source File: ServiceBuilderImpl.ts    From backstage with Apache License 2.0 5 votes vote down vote up
setErrorHandler(errorHandler: ErrorRequestHandler) {
    this.errorHandler = errorHandler;
    return this;
  }
Example #14
Source File: ServiceBuilderImpl.ts    From backstage with Apache License 2.0 5 votes vote down vote up
private errorHandler: ErrorRequestHandler | undefined;
Example #15
Source File: index.ts    From project-loved-web with MIT License 4 votes vote down vote up
db.initialize().then(() => {
  const app = express();
  const sessionLock = new AsyncLock();

  // Hack to add typing to locals
  app.use((_, response, next) => {
    // eslint-disable-next-line regex/invalid
    response.typedLocals = response.locals as Response['typedLocals'];
    next();
  });

  app.use(express.json());

  app.use('/local-interop', hasLocalInteropKeyMiddleware, interopRouter);

  app.use(
    session({
      cookie: {
        httpOnly: true,
        secure: config.httpsAlways,
      },
      name: 'loved_sid',
      proxy: true,
      resave: false,
      saveUninitialized: false,
      secret: config.sessionSecret,
      store: new MysqlSessionStore(
        {
          checkExpirationInterval: 1800000, // 30 minutes
          expiration: 604800000, // 7 days
        },
        db.pool,
      ),
    }),
  );

  app.get('/auth/begin', function (request, response) {
    if (request.session.userId != null) {
      return response.status(403).json({ error: 'Already logged in!' });
    }

    redirectToAuth(request, response, ['identify', 'public']);
  });

  app.get(
    '/auth/callback',
    asyncHandler(async function (request, response) {
      const backUrl = request.session.authBackUrl;
      const state = request.session.authState;
      delete request.session.authBackUrl;
      delete request.session.authState;

      if (request.query.error) {
        if (request.query.error === 'access_denied') {
          return response.redirect(backUrl || '/');
        } else {
          throw request.query.error;
        }
      }

      if (!request.query.code) {
        return response.status(422).json({ error: 'No authorization code provided' });
      }

      if (!request.query.state || request.query.state !== state) {
        return response.status(422).json({ error: 'Invalid state. Try logging in again' });
      }

      const osu = new Osu();
      const scopes: OsuApiScopes = JSON.parse(
        Buffer.from(request.query.state, 'base64url').slice(8).toString(),
      );
      const tokenInfo = await osu.getToken(request.query.code, scopes);
      const user = await osu.createOrRefreshUser();

      if (user == null) {
        throw 'User not found using /me osu! API';
      }

      const logUser = { banned: user.banned, country: user.country, id: user.id, name: user.name };
      const scopesWithoutDefault = scopes.filter(
        (scope) => scope !== 'identify' && scope !== 'public',
      );

      if (scopesWithoutDefault.length > 0) {
        // TODO: Also support upgrading a token to more scopes
        await db.transact(async (connection) => {
          await connection.query('INSERT INTO extra_tokens SET ?', [
            {
              token: JSON.stringify(tokenInfo),
              user_id: user.id,
            },
          ]);
          await dbLog(
            LogType.extraTokenCreated,
            { scopes: scopesWithoutDefault, user: logUser },
            connection,
          );
        });
      } else {
        Object.assign(request.session, tokenInfo);
        request.session.userId = user.id;
        await dbLog(LogType.loggedIn, { user: logUser });
      }

      response.redirect(backUrl || '/');
    }),
  );

  app.use(
    asyncHandler(async function (request, response, next) {
      if (request.session?.userId == null) {
        return next();
      }

      const responseSet = await sessionLock.acquire(request.session.userId.toString(), async () => {
        try {
          // TODO: Requiring reload of session for every authed request is inefficient,
          // but I'm not sure how to split this lock across multiple express middleware.
          // Ideally we would acquire a lock before loading the session at all, and then
          // release it after trying refreshing/saving the osu! auth token.
          await reloadSession(request.session);
        } catch {
          response.status(401).json({ error: 'osu! auth token expired. Try logging in again' });
          return true;
        }

        response.typedLocals.osu = new Osu(request.session);

        try {
          const tokenInfo = await response.typedLocals.osu.tryRefreshToken();

          if (tokenInfo != null) {
            Object.assign(request.session, tokenInfo);
            await saveSession(request.session);
          }
        } catch (error) {
          await destroySession(request.session);

          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          if (typeof error === 'object' && error != null && (error as any).status === 401) {
            // TODO: start a normal re-auth if the refresh token is too old
            response.status(401).json({ error: 'osu! auth token expired. Try logging in again' });
            return true;
          } else {
            throw error;
          }
        }

        return false;
      });

      if (responseSet) {
        return;
      }

      const user = await db.queryOne<UserWithRoles>(
        `
          SELECT *
          FROM users
          WHERE id = ?
        `,
        [request.session.userId],
      );

      if (user == null) {
        throw 'Missing user';
      }

      user.roles = await db.query<UserRole>(
        `
          SELECT *
          FROM user_roles
          WHERE user_id = ?
        `,
        [user.id],
      );

      response.typedLocals.user = user;

      next();
    }),
  );

  app.use(guestRouter);

  // Below here requires authentication
  app.use((request, response, next) => {
    if (!request.session?.userId) {
      return response.status(401).json({ error: 'Log in first' });
    }

    next();
  });

  app.post(
    '/auth/bye',
    asyncHandler(async function (request, response) {
      const user = await response.typedLocals.osu.createOrRefreshUser(request.session.userId);

      if (user == null) {
        throw 'User not found during log out';
      }

      await dbLog(LogType.loggedOut, {
        user: { banned: user.banned, country: user.country, id: user.id, name: user.name },
      });

      await response.typedLocals.osu.revokeToken();
      await destroySession(request.session);

      response.status(204).send();
    }),
  );

  app.get('/auth/remember', function (_, response) {
    response.json(response.typedLocals.user);
  });

  app.use(anyoneRouter);

  // TODO split out this router. "isAnyRoleMiddleware" is here because the permissions aren't all figured out yet, and I want to prevent security issues beyond this point
  app.use(isAnyRoleMiddleware, router);

  app.use(function (_, response) {
    response.status(404).json({ error: 'Not found' });
  });

  // Express relies on there being 4 arguments in the signature of error handlers
  // Also for some reason this has to be typed manually
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  app.use(((error, _request, response, _next) => {
    systemLog(error, SyslogLevel.err);

    response.status(500).json({ error: 'Server error' });
  }) as ErrorRequestHandler);

  const httpServer = app.listen(config.port);
  const httpTerminator = createHttpTerminator({ server: httpServer });

  dbLog(LogType.apiServerStarted);
  systemLog('Starting', SyslogLevel.info);

  function shutdown(): void {
    systemLog('Received exit signal', SyslogLevel.info);

    Promise.allSettled([
      httpTerminator
        .terminate()
        .then(() => systemLog('Closed all HTTP(S) connections', SyslogLevel.info))
        .catch((error) => systemLog(error, SyslogLevel.err)),
      db
        .close()
        .then(() => systemLog('Closed all DB connections', SyslogLevel.info))
        .catch((error) => systemLog(error, SyslogLevel.err)),
    ]).finally(() => {
      systemLog('Exiting', SyslogLevel.info);
      process.exit();
    });
  }

  process.on('SIGINT', shutdown);
  process.on('SIGQUIT', shutdown);
  process.on('SIGTERM', shutdown);
});