Error cat value

A friendly feline companion that helps you create errors, track them, and report them via Rollbar. - GitHub - Runnable/error-cat: A friendly feline companion that helps you create errors, track the...

error-cat

Build Status
Dependency Status
devDependency Status
Code Climate

NPM

A friendly feline companion that helps you build error heirarchies and report
application errors to rollbar.

Basic usage

// Import the library. Uses the environment's `ROLLBAR_KEY` to automatically
// setup rollbar reporting.
const cat = require('error-cat')

// Fire-and-forget error reporting
cat.report(new Error('Something bad'))

// Optionally, pass a callback to execute once the error has been reported
cat.report(new Error('No good'), function () {
  // ...
})

Using error-cat with express

Error cat was designed to be as easy as possible to use with express. Here is an
example of how to do so:

const express = require('express')
const app = express()

// 1. Require error-cat
const cat = require('error-cat')

// 2. Log and report errors using the static responder method
app.use(cat.middleware)

Using error-cat in promise-based applications

Error cat exposes a pass-through promise catch handler that will automatically
report and then re-throw errors in a promise chain. Here’s how to use it:

Promise
  .try(something)
  .then(somethingElse)
  .catch(cat.catch)
  .catch(function (err) {
    // You'll still need this since `ErrorCat.catch` re-throws the error...
  })

Core Error Classes

Error-cat exposes a set of extendable error classes that are specifically
suited to work with the main library. Application programmers can use these
classes to build their own error hierarchies that allow for higher level
error handling and management.

These error classes are very well suited for Promise based applications (for
use with .catch) and try-catch based synchronous applications.

In this section we will show you how to use the provided core error classes and
extend them to create your own error zoology.

Extending Error Classes

Each of the error types, detailed below, can be extended for your own application.
Building a robust error zoology is key in correctly implmenting a try-catch based
error handling strategy in your application.

Error-cat makes this easy, here’s an example of how you can extend the core
base error class to automatically increment an error counter in data-dog (via
monitor-dog) during construction:

'use strict'

const BaseError = require('error-cat/errors/base-error')
const monitor = require('monitor-dog')

/**
 * Base class for all errors that should be monitored in data-dog.
 * @param  {[type]} message Message for the error.
 * @param  {[type]} data    Custom data to report to rollbar.
 */
class MonitoredError extends BaseError {
  constructor (message, data, reporting) {
    super(message, data, reporting)
    monitor.increment('errors')
  }
}

/**
 * Monitored Error Class
 * @module my-application:error
 */
module.exports = MonitoredError

class BaseError(message, data, reporting) extends Error

At the top of the core error hierarchy is BaseError. This class provides the
following:

  1. An easy-to-use and extendable error class for application programmers
  2. Allow for meaningful «extra data»
  3. A method of defining how an error should be reported

Here’s an example that shows everything the base error has to offer:

const BaseError = require('error-cat/errors/base-error')

// Use it as a normal error...
new BaseError('a message')

// Pass data that should be reported in the constructor...
new BaseError('message', { myData: 123 })

// Pass reporting information on how it should be reported...
new BaseError('message', {}, {
  level: 'critical',      // the reporting level
  fingerprint: 'mygroup'  // a grouping fingerprint
})

class Warning(message, data, reporting) extends BaseError

Used to denote an exceptional case that isn’t as serious as an error. By default
these types of errors are not reported.

class RouteError(message, statusCode, data, reporting) extends BaseError

Used to denote exceptions that arise during the handling of RESTful routes.
The class is automatically annotated with additional metadata via the
boom library.

class WorkerError(message, data, reporting, queue, job) extends BaseError

This error class is specifically setup for use in worker servers. It serves as the
root error for the ponos worker server library.
It specifically sets information about the queue name and the job being processed
when the error occured.

Furthermore it exposes two methods that are used by external worker server libraries
for automatically setting this data when task handlers for workers throw this type
of error:

  • (void) setQueue(name) — Sets the queue name data
  • (void) setJob(job) — Sets the job data

class WorkerStopError(message, data, reporting, queue, job) extends WorkerError

Error class that is designed to be thrown when a worker server task handler
encounters a scenario where it cannot possibly proceed with the processing of
the given job. Worker server implementations should automatically acknowledge the
job (even though it was not completed) when encountering this type of error.

class InvalidJobError(message, data, reporting, queue, job) extends WorkerStopError

An error class designed to be thrown when a worker server task handler encounters
a malformed or invalid job.

Reporters

By default ErrorCat reports errors to rollbar. In order to support other services
the library exposes an AbstractReporter class that can be extended as needed.
The only method that is «required» to define in a subclass is .report, but the
class has many other methods that can be easily overriden.

A full treatment of building a custom reporter is outside the scope of this document.
We advise that you simply read the lib/abstract-reporter.js class file thoroughly
(it is fairly short) to get an understanding how to do so.

For usage reference here is an example of how to implement a custom reporter:

const AbstractReporter = require('error-cat/abstract-reporter')
const ErrorCat = require('error-cat/error-cat')
const noop = require('101/noop')

// 1) Define the reporter...
class ConsoleReporter extends AbstractReporter {
  report (err, cb) {
    if (!this.shouldReport(err)) {
      return (cb || noop)()
    }
    console.error(this.getLevel(err), err.message)
  }
}

// 2) Use it with a custom error-cat instance
const cat = new ErrorCat(new ConsoleReporter('warn'))

Contributing

If you wish to contribute to error-cat please adhere to the following rules:

  1. Build and read the jsdoc — npm run doc
  2. Keep test coverage at 100%
  3. When building new components, please use the same OOP style as index.js
  4. For PRs include a good title, and a brief yet informative description of what
    your PR does.

License

MIT

error_cat

A fun way to display python errors.

Do you find long python error tracebacks annoying? Personally, they make me painfully aware of the fact that I don’t know what I’m doing. And while that is certainly the case, sometimes I’d like that news to be delivered to me in a nicer way. For that, there is error_cat.

Installation

pip install error_cat

Usage

error_cat python <name of your favorite python script>.py

If <name of your favorite python script>.py runs successfully, you will see a fun, reassuring message from error_cat:

                ________________________
               /                        
               |   Everything worked!   |
                 ______________________/
              /  /
 ,_     _    / /
 |\_,-~/   /'
 / _  _ |    ,--.
(  @  @ )   / ,-'
   _T_/-._( (
 /         `. 
|         _   |
   ,  /      |
  || |-___   /
 ((_/`(____,-'

On the other hand, if <name of your favorite python script>.py produces an error, error_cat will break the news to you. Here is an example script that will lead to an error:

fake_error.py

def func():
	func2()

def func2():
	print(5 + "5")

func()

Here is what error_cat will tell you:

$ error_cat python fake_error.py

                _________________________________________________________________
               /                                                                 
               |   File "fake_error.py", line 5, in func2                        |
               |   TypeError: unsupported operand types for +: 'int' and 'str'   |
                 _______________________________________________________________/
              /  /
 ,_     _    / /
 |\_,-~/   /'
 / _  _ |    ,--.
(  @  @ )   / ,-'
   _T_/-._( (
 /         `. 
|         _   |
   ,  /      |
  || |-___   /
 ((_/`(____,-'

Artwork Credit

All ascii artwork is from the ASCII Art Archive. Individual artworks are credited to the artist (if known) in the comments of error_cat/characters.py. A big thank you to the following artists whose art has been incorporated into error_cat:

  • Morfina
  • Joan G. Stark

Represents an HTTP error. This class holds an error message and an optional error code.
More…

#include <http_msg.h>

Public Member Functions

  http_exception (const utility::string_t &whatArg)
  Creates an http_exception with just a string message and no error code. More…
 
  http_exception (int errorCode)
  Creates an http_exception with from a error code using the current platform error category. The message of the error code will be used as the what() string message. More…
 
  http_exception (int errorCode, const utility::string_t &whatArg)
  Creates an http_exception with from a error code using the current platform error category. More…
 
  http_exception (int errorCode, const std::error_category &cat)
  Creates an http_exception with from a error code and category. The message of the error code will be used as the what string message. More…
 
const char *  what () const CPPREST_NOEXCEPT
  Gets a string identifying the cause of the exception. More…
 
const std::error_code &  error_code () const
  Retrieves the underlying error code causing this exception. More…
 

Represents an HTTP error. This class holds an error message and an optional error code.

web::http::http_exception::http_exception ( const utility::string_t &  whatArg )
inline

Creates an http_exception with just a string message and no error code.

Parameters
whatArg Error message string.
web::http::http_exception::http_exception ( int  errorCode )
inline

Creates an http_exception with from a error code using the current platform error category. The message of the error code will be used as the what() string message.

Parameters
errorCode Error code value.
web::http::http_exception::http_exception ( int  errorCode,
const utility::string_t &  whatArg 
)
inline

Creates an http_exception with from a error code using the current platform error category.

Parameters
errorCode Error code value.
whatArg Message to use in what() string.
web::http::http_exception::http_exception ( int  errorCode,
const std::error_category &  cat 
)
inline

Creates an http_exception with from a error code and category. The message of the error code will be used as the what string message.

Parameters
errorCode Error code value.
cat Error category for the code.
const std::error_code& web::http::http_exception::error_code ( ) const
inline

Retrieves the underlying error code causing this exception.

Returns
A std::error_code.
const char* web::http::http_exception::what ( ) const
inline

Gets a string identifying the cause of the exception.

Returns
A null terminated character string.

The documentation for this class was generated from the following file:

  • include/cpprest/http_msg.h

I think you want to capture stderr, stdout and exitcode if that is your intention you can use this code:

## Capture error when 'some_command() is executed
some_command_with_err() {
    echo 'this is the stdout'
    echo 'this is the stderr' >&2
    exit 1
}

run_command() {
    {
        IFS=$'n' read -r -d '' stderr;
        IFS=$'n' read -r -d '' stdout;
        IFS=$'n' read -r -d '' stdexit;
    } < <((printf '%s%d' "$(some_command_with_err)" "${?}" 1>&2) 2>&1)
    stdexit=${stdexit:-0};
}

echo 'Run command:'
if ! run_command; then
    ## Show the values
    typeset -p stdout stderr stdexit
else
    typeset -p stdout stderr stdexit
fi

This scripts capture the stderr, stdout as well as the exitcode.

But Teo how it works?

First, we capture the stdout as well as the exitcode using printf '%s%d'. They are separated by the aka ‘null byte’.

After that, we redirect the printf to stderr by doing: 1>&2 and then we redirect all back to stdout using 2>&1. Therefore, the stdout will look like:

"<stderr><stdout><exitcode>"

Enclosing the printf command in <( ... ) performs process substitution. Process substitution allows a process’s input or output to be referred to using a filename. This means <( ... ) will pipe the stdout of (printf '%s%d' "$(some_command_with_err)" "${?}" 1>&2) 2>&1into the stdin of the command group using the first <.

Then, we can capture the piped stdout from the stdin of the command group with read. This command reads a line from the file descriptor stdin and split it into fields. Only the characters found in $IFS are recognized as word delimiters. $IFS or Internal Field Separator is a variable that determines how Bash recognizes fields, or word boundaries, when it interprets character strings. $IFS defaults to whitespace (space, tab, and newline), but may be changed, for example, to parse a comma-separated data file. Note that $* uses the first character held in $IFS.

## Shows whitespace as a single space, ^I(horizontal tab), and newline, and display "$" at end-of-line.
echo "$IFS" | cat -vte
# Output:
# ^I$
# $

## Reads commands from string and assign any arguments to pos params
bash -c 'set w x y z; IFS=":-;"; echo "$*"'
# Output:
# w:x:y:z

for l in $(printf %b 'a bnc'); do echo "$l"; done
# Output: 
# a
# b
# c

IFS=$'n'; for l in $(printf %b 'a bnc'); do echo "$l"; done
# Output: 
# a b
# c

That is why we defined IFS=$'n' (newline) as delimiter.
Our script uses read -r -d '', where read -r does not allow backslashes to escape any characters, and -d '' continues until the first character '' is read, rather than newline.

Finally, replace some_command_with_err with your script file and you can capture and handle the stderr, stdout as well as the exitcode as your will.

Before we get into the specifics of validation syntax, please keep the following rules in mind:

  • Validation is defined in the SchemaType
  • Validation is middleware. Mongoose registers validation as a pre('save') hook on every schema by default.
  • You can disable automatic validation before save by setting the validateBeforeSave option
  • You can manually run validation using doc.validate(callback) or doc.validateSync()
  • You can manually mark a field as invalid (causing validation to fail) by using doc.invalidate(...)
  • Validators are not run on undefined values. The only exception is the required validator.
  • Validation is asynchronously recursive; when you call Model#save, sub-document validation is executed as well. If an error occurs, your Model#save callback receives it
  • Validation is customizable
const schema = new Schema({
  name: {
    type: String,
    required: true
  }
});
const Cat = db.model('Cat', schema);

// This cat has no name :(
const cat = new Cat();

let error;
try {
  await cat.save();
} catch (err) {
  error = err;
}
    
assert.equal(error.errors['name'].message,
  'Path `name` is required.');

error = cat.validateSync();
assert.equal(error.errors['name'].message,
  'Path `name` is required.');
  • Built-in Validators
  • Custom Error Messages
  • The unique Option is Not a Validator
  • Custom Validators
  • Async Custom Validators
  • Validation Errors
  • Cast Errors
  • Global SchemaType Validation
  • Required Validators On Nested Objects
  • Update Validators
  • Update Validators and this
  • Update Validators Only Run On Updated Paths
  • Update Validators Only Run For Some Operations

Built-in Validators

Mongoose has several built-in validators.

  • All SchemaTypes have the built-in required validator. The required validator uses the SchemaType’s checkRequired() function to determine if the value satisfies the required validator.
  • Numbers have min and max validators.
  • Strings have enum, match, minLength, and maxLength validators.

Each of the validator links above provide more information about how to enable them and customize their error messages.

const breakfastSchema = new Schema({
  eggs: {
    type: Number,
    min: [6, 'Too few eggs'],
    max: 12
  },
  bacon: {
    type: Number,
    required: [true, 'Why no bacon?']
  },
  drink: {
    type: String,
    enum: ['Coffee', 'Tea'],
    required: function() {
      return this.bacon > 3;
    }
  }
});
const Breakfast = db.model('Breakfast', breakfastSchema);

const badBreakfast = new Breakfast({
  eggs: 2,
  bacon: 0,
  drink: 'Milk'
});
let error = badBreakfast.validateSync();
assert.equal(error.errors['eggs'].message,
  'Too few eggs');
assert.ok(!error.errors['bacon']);
assert.equal(error.errors['drink'].message,
  '`Milk` is not a valid enum value for path `drink`.');

badBreakfast.bacon = 5;
badBreakfast.drink = null;

error = badBreakfast.validateSync();
assert.equal(error.errors['drink'].message, 'Path `drink` is required.');

badBreakfast.bacon = null;
error = badBreakfast.validateSync();
assert.equal(error.errors['bacon'].message, 'Why no bacon?');

Custom Error Messages

You can configure the error message for individual validators in your schema. There are two equivalent
ways to set the validator error message:

  • Array syntax: min: [6, 'Must be at least 6, got {VALUE}']
  • Object syntax: enum: { values: ['Coffee', 'Tea'], message: '{VALUE} is not supported' }

Mongoose also supports rudimentary templating for error messages.
Mongoose replaces {VALUE} with the value being validated.

const breakfastSchema = new Schema({
  eggs: {
    type: Number,
    min: [6, 'Must be at least 6, got {VALUE}'],
    max: 12
  },
  drink: {
    type: String,
    enum: {
      values: ['Coffee', 'Tea'],
      message: '{VALUE} is not supported'
    }
  }
});
const Breakfast = db.model('Breakfast', breakfastSchema);

const badBreakfast = new Breakfast({
  eggs: 2,
  drink: 'Milk'
});
const error = badBreakfast.validateSync();
assert.equal(error.errors['eggs'].message,
  'Must be at least 6, got 2');
assert.equal(error.errors['drink'].message, 'Milk is not supported');

The unique Option is Not a Validator

A common gotcha for beginners is that the unique option for schemas
is not a validator. It’s a convenient helper for building MongoDB unique indexes.
See the FAQ for more information.

const uniqueUsernameSchema = new Schema({
  username: {
    type: String,
    unique: true
  }
});
const U1 = db.model('U1', uniqueUsernameSchema);
const U2 = db.model('U2', uniqueUsernameSchema);

const dup = [{ username: 'Val' }, { username: 'Val' }];
U1.create(dup, err => {
  // Race condition! This may save successfully, depending on whether
  // MongoDB built the index before writing the 2 docs.
});

// You need to wait for Mongoose to finish building the `unique`
// index before writing. You only need to build indexes once for
// a given collection, so you normally don't need to do this
// in production. But, if you drop the database between tests,
// you will need to use `init()` to wait for the index build to finish.
U2.init().
  then(() => U2.create(dup)).
  catch(error => {
    // Will error, but will *not* be a mongoose validation error, it will be
    // a duplicate key error.
    // See: https://masteringjs.io/tutorials/mongoose/e11000-duplicate-key
    assert.ok(error);
    assert.ok(!error.errors);
    assert.ok(error.message.indexOf('duplicate key error') !== -1);
  });

Custom Validators

If the built-in validators aren’t enough, you can define custom validators
to suit your needs.

Custom validation is declared by passing a validation function.
You can find detailed instructions on how to do this in the
SchemaType#validate() API docs.

const userSchema = new Schema({
  phone: {
    type: String,
    validate: {
      validator: function(v) {
        return /d{3}-d{3}-d{4}/.test(v);
      },
      message: props => `${props.value} is not a valid phone number!`
    },
    required: [true, 'User phone number required']
  }
});

const User = db.model('user', userSchema);
const user = new User();
let error;

user.phone = '555.0123';
error = user.validateSync();
assert.equal(error.errors['phone'].message,
  '555.0123 is not a valid phone number!');

user.phone = '';
error = user.validateSync();
assert.equal(error.errors['phone'].message,
  'User phone number required');

user.phone = '201-555-0123';
// Validation succeeds! Phone number is defined
// and fits `DDD-DDD-DDDD`
error = user.validateSync();
assert.equal(error, null);

Async Custom Validators

Custom validators can also be asynchronous. If your validator function
returns a promise (like an async function), mongoose will wait for that
promise to settle. If the returned promise rejects, or fulfills with
the value false, Mongoose will consider that a validation error.

const userSchema = new Schema({
  name: {
    type: String,
    // You can also make a validator async by returning a promise.
    validate: () => Promise.reject(new Error('Oops!'))
  },
  email: {
    type: String,
    // There are two ways for an promise-based async validator to fail:
    // 1) If the promise rejects, Mongoose assumes the validator failed with the given error.
    // 2) If the promise resolves to `false`, Mongoose assumes the validator failed and creates an error with the given `message`.
    validate: {
      validator: () => Promise.resolve(false),
      message: 'Email validation failed'
    }
  }
});

const User = db.model('User', userSchema);
const user = new User();

user.email = 'test@test.co';
user.name = 'test';

let error;
try {
  await user.validate();
} catch (err) {
  error = err;
}
assert.ok(error);
assert.equal(error.errors['name'].message, 'Oops!');
assert.equal(error.errors['email'].message, 'Email validation failed');

Validation Errors

Errors returned after failed validation contain an errors object
whose values are ValidatorError objects. Each
ValidatorError has kind, path,
value, and message properties.
A ValidatorError also may have a reason property. If an error was
thrown in the validator, this property will contain the error that was
thrown.

const toySchema = new Schema({
  color: String,
  name: String
});

const validator = function(value) {
  return /red|white|gold/i.test(value);
};
toySchema.path('color').validate(validator,
  'Color `{VALUE}` not valid', 'Invalid color');
toySchema.path('name').validate(function(v) {
  if (v !== 'Turbo Man') {
    throw new Error('Need to get a Turbo Man for Christmas');
  }
  return true;
}, 'Name `{VALUE}` is not valid');

const Toy = db.model('Toy', toySchema);

const toy = new Toy({ color: 'Green', name: 'Power Ranger' });

let error;
try {
  await toy.save();
} catch(err) {
  error = err;
}
    
// `error` is a ValidationError object
// `error.errors.color` is a ValidatorError object
assert.equal(error.errors.color.message, 'Color `Green` not valid');
assert.equal(error.errors.color.kind, 'Invalid color');
assert.equal(error.errors.color.path, 'color');
assert.equal(error.errors.color.value, 'Green');

// If your validator throws an exception, mongoose will use the error
// message. If your validator returns `false`,
// mongoose will use the 'Name `Power Ranger` is not valid' message.
assert.equal(error.errors.name.message,
  'Need to get a Turbo Man for Christmas');
assert.equal(error.errors.name.value, 'Power Ranger');
// If your validator threw an error, the `reason` property will contain
// the original error thrown, including the original stack trace.
assert.equal(error.errors.name.reason.message,
  'Need to get a Turbo Man for Christmas');

assert.equal(error.name, 'ValidationError');

Cast Errors

Before running validators, Mongoose attempts to coerce values to the
correct type. This process is called casting the document. If
casting fails for a given path, the error.errors object will contain
a CastError object.

Casting runs before validation, and validation does not run if casting
fails. That means your custom validators may assume v is null,
undefined, or an instance of the type specified in your schema.

const vehicleSchema = new mongoose.Schema({
  numWheels: { type: Number, max: 18 }
});
const Vehicle = db.model('Vehicle', vehicleSchema);

const doc = new Vehicle({ numWheels: 'not a number' });
const err = doc.validateSync();

err.errors['numWheels'].name; // 'CastError'
// 'Cast to Number failed for value "not a number" at path "numWheels"'
err.errors['numWheels'].message;

Global SchemaType Validation

In addition to defining custom validators on individual schema paths, you can also configure a custom validator to run on every instance of a given SchemaType.
For example, the following code demonstrates how to make empty string '' an invalid value for all string paths.

// Add a custom validator to all strings
mongoose.Schema.Types.String.set('validate', v => v == null || v > 0);

const userSchema = new Schema({
  name: String,
  email: String
});
const User = db.model('User', userSchema);

const user = new User({ name: '', email: '' });

const err = await user.validate().then(() => null, err => err);
err.errors['name']; // ValidatorError
err.errors['email']; // ValidatorError

Required Validators On Nested Objects

Defining validators on nested objects in mongoose is tricky, because
nested objects are not fully fledged paths.

let personSchema = new Schema({
  name: {
    first: String,
    last: String
  }
});

assert.throws(function() {
  // This throws an error, because 'name' isn't a full fledged path
  personSchema.path('name').required(true);
}, /Cannot.*'required'/);

// To make a nested object required, use a single nested schema
const nameSchema = new Schema({
  first: String,
  last: String
});

personSchema = new Schema({
  name: {
    type: nameSchema,
    required: true
  }
});

const Person = db.model('Person', personSchema);

const person = new Person();
const error = person.validateSync();
assert.ok(error.errors['name']);

Update Validators

In the above examples, you learned about document validation. Mongoose also
supports validation for update(),
updateOne(),
updateMany(),
and findOneAndUpdate() operations.
Update validators are off by default — you need to specify
the runValidators option.

To turn on update validators, set the runValidators option for
update(), updateOne(), updateMany(), or findOneAndUpdate().
Be careful: update validators are off by default because they have several
caveats.

const toySchema = new Schema({
  color: String,
  name: String
});

const Toy = db.model('Toys', toySchema);

Toy.schema.path('color').validate(function(value) {
  return /red|green|blue/i.test(value);
}, 'Invalid color');

const opts = { runValidators: true };

let error;
try {
  await Toy.updateOne({}, { color: 'not a color' }, opts);
} catch (err) {
  error = err;
}

assert.equal(error.errors.color.message, 'Invalid color');

Update Validators and this

There are a couple of key differences between update validators and
document validators. In the color validation function below, this refers
to the document being validated when using document validation.
However, when running update validators, this refers to the query object instead of the document.
Because queries have a neat .get() function, you can get the updated value of the property you want.

const toySchema = new Schema({
  color: String,
  name: String
});

toySchema.path('color').validate(function(value) {
  // When running in `validate()` or `validateSync()`, the
  // validator can access the document using `this`.
  // When running with update validators, `this` is the Query,
  // **not** the document being updated!
  // Queries have a `get()` method that lets you get the
  // updated value.
  if (this.get('name') && this.get('name').toLowerCase().indexOf('red') !== -1) {
    return value === 'red';
  }
  return true;
});

const Toy = db.model('ActionFigure', toySchema);

const toy = new Toy({ color: 'green', name: 'Red Power Ranger' });
// Validation failed: color: Validator failed for path `color` with value `green`
let error = toy.validateSync();
assert.ok(error.errors['color']);

const update = { color: 'green', name: 'Red Power Ranger' };
const opts = { runValidators: true };

error = null;
try {
  await Toy.updateOne({}, update, opts);
} catch (err) {
  error = err;
}
// Validation failed: color: Validator failed for path `color` with value `green`
assert.ok(error);

Update Validators Only Run On Updated Paths

The other key difference is that update validators only run on the paths
specified in the update. For instance, in the below example, because
‘name’ is not specified in the update operation, update validation will
succeed.

When using update validators, required validators only fail when
you try to explicitly $unset the key.

const kittenSchema = new Schema({
  name: { type: String, required: true },
  age: Number
});

const Kitten = db.model('Kitten', kittenSchema);

const update = { color: 'blue' };
const opts = { runValidators: true };
Kitten.updateOne({}, update, opts, function() {
  // Operation succeeds despite the fact that 'name' is not specified
});

const unset = { $unset: { name: 1 } };
Kitten.updateOne({}, unset, opts, function(err) {
  // Operation fails because 'name' is required
  assert.ok(err);
  assert.ok(err.errors['name']);
});

Update Validators Only Run For Some Operations

One final detail worth noting: update validators only run on the
following update operators:

  • $set
  • $unset
  • $push
  • $addToSet
  • $pull
  • $pullAll

For instance, the below update will succeed, regardless of the value of
number, because update validators ignore $inc.

Also, $push, $addToSet, $pull, and $pullAll validation does
not run any validation on the array itself, only individual elements
of the array.

const testSchema = new Schema({
  number: { type: Number, max: 0 },
  arr: [{ message: { type: String, maxlength: 10 } }]
});

// Update validators won't check this, so you can still `$push` 2 elements
// onto the array, so long as they don't have a `message` that's too long.
testSchema.path('arr').validate(function(v) {
  return v.length < 2;
});

const Test = db.model('Test', testSchema);

let update = { $inc: { number: 1 } };
const opts = { runValidators: true };

// There will never be a validation error here
await Test.updateOne({}, update, opts);

// This will never error either even though the array will have at
// least 2 elements.
update = { $push: [{ message: 'hello' }, { message: 'world' }] };
await Test.updateOne({}, update, opts);

Next Up

Now that we’ve covered Validation, let’s take a look at Middleware.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Error case label does not reduce to an integer constant
  • Error card sd hansa что делать
  • Error card sd hansa bccw69369055
  • Error car invalid argument 1 wrong type not a pair
  • Error code 0x0000007e

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии