Skip to main content

wrapper function

A wrapper function is a function that wraps another function or piece of code to add extra behavior, control, or simplify the call.

In simpler terms:

A wrapper function is a "layer" around another function that breaks nothing, but adds something: logging, validation, error handling, caching, and so on.


Main idea

You take an existing function (or operation) and create a new one that calls it inside itself, but with something "on top".

For example:

  • add logging before the call;
  • measure the execution time;
  • add argument validation;
  • or, for example, handle errors via try/catch.

Example 1 - a simple wrapper with logging

javascript
function greet(name) { return `Hello, ${name}!`; } function withLogging(fn) { return function(...args) { console.log(`Calling function ${fn.name} with arguments:`, args); const result = fn(...args); console.log(`Result:`, result); return result; }; } const loggedGreet = withLogging(greet); loggedGreet('Tim');

Output:

javascript
Calling function greet with arguments: [ 'Tim' ] Result: Hello, Tim!

Here withLogging is a wrapper function that adds extra behavior "on top" of the regular greet function.


Example 2 - a wrapper for error handling

javascript
function riskyOperation() { throw new Error('Something went wrong!'); } function safeWrapper(fn) { return function(...args) { try { return fn(...args); } catch (err) { console.error('Error calling the function:', err.message); return null; } }; } const safeOp = safeWrapper(riskyOperation); safeOp(); // Error calling the function: Something went wrong!

Now even if the inner function throws, the code does not break.


Example 3 - measuring execution time

javascript
function heavyTask() { for (let i = 0; i < 1e7; i++) {} } function measureTime(fn) { return function(...args) { const start = performance.now(); fn(...args); const end = performance.now(); console.log(`Execution time: ${(end - start).toFixed(2)}ms`); }; } const measuredTask = measureTime(heavyTask); measuredTask(); // Execution time: 12.34ms

Example 4 - a wrapper function in async code

javascript
async function fetchData() { const res = await fetch('https://api.example.com/data'); return res.json(); } function withErrorHandling(fn) { return async function(...args) { try { return await fn(...args); } catch (e) { console.error('Request error:', e); return null; } }; } const safeFetch = withErrorHandling(fetchData); safeFetch();

This is already an async wrapper that automatically catches errors.


Example 5 - a wrapper for "decorators" (a similar pattern)

javascript
function authWrapper(fn) { return function(user, ...args) { if (!user.isAdmin) { throw new Error('Access denied'); } return fn(user, ...args); }; } function deletePost(user, postId) { console.log(`Post ${postId} deleted`); } const deletePostWithAuth = authWrapper(deletePost); deletePostWithAuth({ isAdmin: true }, 42); // Post 42 deleted deletePostWithAuth({ isAdmin: false }, 42); // Error: Access denied

Why wrapper functions are useful

GoalExample
Extending functionalityAdd logging, metrics, caching
SecurityCheck access rights or a token
Error handlingWrap risky operations in try/catch
ReuseCreate a "behavior" template for many functions
Functional programmingUse higher-order functions

Summary

PropertyDescription
What it isA function that calls another one inside itself
GoalAdd or change behavior without changing the original
TypeHigher-order function
Typical examplesLogging, cache, validation, try/catch, metrics
ProsReusable, safe, readable

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.