@@ -589,6 +589,68 @@ void InitializeHttpParser(Local<Object> target,
589589}
590590``` 
591591
592+ ### Argument validation in public APIs vs. internal code 
593+ 
594+ #### Public API argument sanitization 
595+ 
596+ When arguments come directly from user code, Node.js will typically validate them at the 
597+ JavaScript layer and throws user-friendly 
598+ [errors](https://github.com/nodejs/node/blob/main/doc/contributing/using-internal-errors.md) 
599+ (e.g., `ERR_INVALID_*`), if they are invalid. This helps end users 
600+ quickly understand and fix mistakes in their own code. 
601+ 
602+ This approach ensures that the error message pinpoints which argument is wrong 
603+ and how it should be fixed. Additionally, problems in user code do not cause 
604+ mysterious crashes or hard-to-diagnose failures deeper in the engine. 
605+ 
606+ Example from `zlib.js`: 
607+ 
608+ ```js 
609+ function crc32(data, value = 0) { 
610+   if (typeof data !== 'string' && !isArrayBufferView(data)) { 
611+     throw new ERR_INVALID_ARG_TYPE('data', ['Buffer', 'TypedArray', 'DataView','string'], data); 
612+   } 
613+   validateUint32(value, 'value'); 
614+   return crc32Native(data, value); 
615+ } 
616+ ``` 
617+ 
618+ The corresponding C++ assertion code for the above example from it's binding ` node_zlib.cc ` :
619+ 
620+ ``` cpp 
621+ CHECK (args[ 0] ->IsArrayBufferView() || args[ 0] ->IsString());
622+ CHECK(args[ 1] ->IsUint32());
623+ ``` 
624+ 
625+ #### Internal code and C++ binding checks 
626+ 
627+ Inside Node.js’s internal layers, especially the C++ [binding function][]s 
628+ typically assume their arguments have already been checked and sanitized 
629+ by the upper-level (JavaScript) callers. As a result, internal C++ code 
630+ often just uses `CHECK()` or similar assertions to confirm that the 
631+ types/values passed in are correct. If that assertion fails, Node.js will 
632+ crash or abort with an internal diagnostic message. This is to avoid 
633+ re-validating every internal function argument repeatedly which can slow 
634+ down the system. 
635+ 
636+ However, in a less common case where the API is implemented completely in 
637+ C++, the arguments would be validated directly in C++, with the errors 
638+ thrown using `THROW_ERR_INVALID_*` macros from `src/node_errors.h`. 
639+ 
640+ For example in `worker_threads.moveMessagePortToContext`: 
641+ 
642+ ```cpp 
643+ void MessagePort::MoveToContext(const FunctionCallbackInfo<Value>& args) { 
644+   Environment* env = Environment::GetCurrent(args); 
645+   if (!args[0]->IsObject() || 
646+       !env->message_port_constructor_template()->HasInstance(args[0])) { 
647+     return THROW_ERR_INVALID_ARG_TYPE(env, 
648+         "The \"port\" argument must be a MessagePort instance"); 
649+   } 
650+   // ... 
651+ } 
652+ ``` 
653+ 
592654<a  id =" exception-handling " ></a >
593655
594656### Exception handling  
0 commit comments