In Playwright, fixtures are reusable setup and teardown utilities that help you share test data, page objects, authentication, API clients, and configurations across tests.
Custom fixtures make your framework:
Reusable
Maintainable
Scalable
Cleaner and easier to read
1. What is a Fixture in Playwright?
A fixture is a setup environment provided to your test before execution.
Playwright already provides built-in fixtures such as:
Exception handling in JavaScript is used to manage runtime errors without stopping the entire program. It helps developers write stable and reliable applications.
What is an Exception?
An exception is an unexpected error that occurs while the program is running.
Examples:
Dividing by invalid values
Accessing undefined variables
Invalid JSON parsing
Network/API failures
Custom validation errors
Why Exception Handling is Important
Exception handling helps to:
Prevent application crashes
Show meaningful error messages
Debug applications easily
Handle API/database failures gracefully
Improve user experience
1. The Core Structure: try...catch
The try block contains code that might throw an error. If an error occurs, JavaScript immediately stops executing the try block and jumps to the catch block.
JavaScript
try {
// Code that might fail
let result = 10 / unknownVariable;
console.log("This line will not run");
} catch (error) {
// Code to handle the error
console.log("An error occurred:", error.message);
}
console.log("Execution continues normally.");
2. Standard Error Properties
Inside the catch block, the error object provides valuable diagnostic metadata:
error.name: The type of error (e.g., ReferenceError, TypeError).
error.message: A human-readable description of what went wrong.
error.stack: The stack trace showing where the error occurred in the source files.
The optional finally block always executes, regardless of whether an error occurred or was caught. It is ideal for cleanup tasks (e.g., closing file streams, resetting UI states, or clearing timers).
You can trigger explicit errors using the throw statement. While you can throw primitives (strings or numbers), it is best practice to throw standard Error objects so you retain stack trace information.
JavaScript
function withdrawMoney(amount, balance) {
if (typeof amount !== 'number') {
throw new TypeError("Amount must be a number");
}
if (amount > balance) {
throw new Error("Insufficient funds for this withdrawal");
}
return balance - amount;
}
try {
let newBalance = withdrawMoney(150, 100);
} catch (err) {
console.log(`[${err.name}] ${err.message}`);
}
5. Built-in JavaScript Error Types
Understanding common built-in error classes helps you diagnose issues quickly:
Error Type
Trigger Cause
Example
ReferenceError
Accessing an undeclared variable
console.log(x);
TypeError
Performing an invalid operation on a value
"text".toUpperCase() works, but (123).toUpperCase() fails
SyntaxError
Invalid JavaScript syntax (usually caught at parse time)
JSON.parse("{ bad json }")
RangeError
A numeric variable or parameter is outside its valid range
new Array(-1)
6. Asynchronous Exception Handling
Traditional try...catch blocks cannot catch errors inside asynchronous callbacks or promises because the try block finishes executing before the async callback runs.
Promises
Use the .catch() method to handle rejected promises:
JavaScript
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("API server offline")), 1000);
});
}
fetchData()
.then(data => console.log(data))
.catch(err => console.log("Promise Error:", err.message));
async / await
With async / await, you can wrap asynchronous code in a standard try...catch block:
JavaScript
async function loadUserData() {
try {
let response = await fetchData(); // Waits for promise resolution/rejection
console.log(response);
} catch (err) {
console.log("Async/Await Error:", err.message);
}
}
loadUserData();
JavaScript provides standard built-in error constructors that inherit from the base Error object. Each error type corresponds to a specific category of runtime exception.
1. Core Built-In Error Types
Error (Generic Base Error)
The generic base object used for general exceptions or as a parent class for custom user-defined errors.
JavaScript
try {
throw new Error("Application failed to process the request.");
} catch (err) {
console.log(err.name); // "Error"
console.log(err.message); // "Application failed to process the request."
}
TypeError
Occurs when an operation is performed on a value of an unexpected data type, such as attempting to invoke a non-function or reading properties of null/undefined.
JavaScript
try {
const count = 42;
count.toUpperCase(); // TypeError: count.toUpperCase is not a function
} catch (err) {
console.log(err.name); // "TypeError"
}
ReferenceError
Occurs when trying to access or dereference a variable that does not exist or has not been initialized (such as accessing a let/const variable in its Temporal Dead Zone).
Occurs when code violates JavaScript language syntax rules. Parsing utilities like JSON.parse() or eval() throw runtime SyntaxErrors when passed malformed input.
Occurs when a numeric value or function argument falls outside its allowed range or bounds (e.g., invalid array lengths, out-of-bounds numbers in .toFixed(), or max stack size recursion).
Introduced in ES2021, AggregateError wraps multiple errors into a single error object. It is automatically thrown by Promise.any() when every promise passed to it rejects.
Introduced with Explicit Resource Management (using declarations). It occurs when an error is thrown during the cleanup/disposal of a resource while another error was already active.
JavaScript
try {
// Represents a primary error and a secondary disposal error
throw new SuppressedError(
new Error("Cleanup failed"), // The new error during disposal
new Error("Main logic failed"), // The original suppressed error
"Resource disposal failure"
);
} catch (err) {
console.log(err.error.message); // "Cleanup failed"
console.log(err.suppressed.message); // "Main logic failed"
}
EvalError
A legacy error object created for issues related to the global eval() function. While modern JS engines no longer throw native EvalErrors (favoring SyntaxError or TypeError instead), the constructor remains in the language specification for backwards compatibility.