Code Monkey home page Code Monkey logo

error-handling-spring-boot-starter's Introduction

Error Handling Spring Boot Starter

Goal

The goal of the project is to make it easy to have proper and consistent error responses for REST APIs build with Spring Boot.

Documentation

If you are new to the library, check out Better Error Handling for Your Spring Boot REST APIs for an introductory overview.

ℹ️
Documentation is very important to us, so if you find something missing from the docs, please create an issue about it.

Spring Boot compatibility

error-handling-spring-boot-starter Spring Boot Minimum Java version Docs

4.3.0

3.x

17

Documentation 4.3.0

4.2.0

3.x

17

Documentation 4.2.0

4.1.3

3.x

17

Documentation 4.1.3

4.0.0

3.0.x

17

Documentation 4.0.0

3.4.1

2.7.x

11

Documentation 3.4.1

3.3.0

2.7.x

11

Documentation 3.3.0

3.2.0

2.5.x

11

N/A

2.1.0

2.5.x

11

N/A

Articles

Blogs and articles about this library:

Release

Release is done via the Maven Release Plugin:

mvn release:prepare

and

mvn release:perform

Merge the tag to master so the documentation is updated.

Finally, push the local commits and the tag to remote.

ℹ️

Before releasing, run export GPG_TTY=$(tty)

error-handling-spring-boot-starter's People

Contributors

dmitriusan avatar fabiomarini avatar ooraini avatar rubensa avatar sdoxsee avatar sivaprasadreddy avatar wimdeblauwe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

error-handling-spring-boot-starter's Issues

Handling exceptions from filters

Hi,

I'm trying to catch exceptions thrown from Spring Filters with ErrorHandlingControllerAdvice. I'm aware that @ControllerAdvice annotated classes aren't meant to catch those exceptions, which is why I'm implementing something similar to what's described here: https://stackoverflow.com/a/55864206/14789719

The problem I'm having is that HandlerExceptionResolver.resolveException() doesn't call ErrorHandlingControllerAdvice to handle the exception. I think this is because Spring sees that ErrorHandlingControllerAdvice is annotated with @ControllerAdivce(annotations = RestController.class) which tells Spring that it should only call it to handle exceptions thrown from @RestController annotated classes.

I understand that, in normal circumstances, that is the obvious and desired functionality, but it would be really convenient for me to call ErrorHandlingControllerAdvice from filters. Do you think there is some way to accomodate my use case?

Thank you very much for your time and for the library.

Log 500 exceptions with stack traces

I see that error.handling.exception-logging lets you toggle between WITH_STACKTRACE and MESSAGE_ONLY. And that full-stacktrace-classes lets you affect the behavior. But the way I look at 500 Internal Server Errors versus everything else is as follows:

  • 500 Internal Server Error: undefined behavior happened, the developer did not account for this, someone needs to evaluate this for future improvement. To support this troubleshooting, I would like these to be logged with stack traces
  • All other errors: defined behavior, as undesirable as it may be, though often it's caused by bad requests from the client. To not overwhelm the log file, I would like these to be logged without stack traces

Unfortunately, the logging configuration described here is not currently possible. I would like a boolean property that would cause exceptions being logged for all 5xx or 500 status codes, and message-only for all others. Or a range, or something.

The fact that, to me, 500 status codes maps to undefined behavior also makes it undesirable to define exceptions ahead of time in full-stacktrace-classes.

Thank you for this useful library!

Allow setting if null values should be included in response or not

When a property from the Exception is added to the JSON via @ResponseErrorProperty, it is now always serialized, even if the value of that property is null.

It would be better to not serialize such properties by default. But allowing to restore the current behaviour via a setting on the annotation.

HttpRequestMethodNotSupportedException

Out of the box when I make an API call to a method not implemented yet, HttpRequestMethodNotSupportedException exception is thrown which does not get handled and Spring handles this exception with its own handler and formats with the big stack trace and message

"error": "Method Not Allowed",
"message": "Request method 'GET' not supported",
"path": "/v1/api"

I tried to override it following examples

    http-statuses:
      org:
        springframework:
          web:
            HttpRequestMethodNotSupportedException: method_not_allowed

However it did not work .I think it is likely because Spring handles this exception before any of the custom exception handler can get to it. If that is what is happening I think it is better to register custom handlers before spring handlers with something like this @Order(Ordered.HIGHEST_PRECEDENCE)

exception-logging is showing stacktrace with MESSAGE_ONLY option

Hi,

I'm using 3.4.0, given the following endpoint

@GetMapping
public Person get() {
    throw new RuntimeException("testing");
}

And no configuration, because default is MESSAGE_ONLY

error:
  handling:
    exception-logging: MESSAGE_ONLY

The output will be

2023-03-12 02:16:51.348 ERROR 279524 --- [nio-8080-exec-2] i.g.w.e.LoggingService                   : testing

java.lang.RuntimeException: testing
        at com.bwgjoseph.springbootdebeziummongodbes.mongo.PersonController.get(PersonController.java:51) ~[classes/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        // omitted

If you change the configuration to

error:
  handling:
    exception-logging: WITH_STACKTRACE

The output is exactly the same.

I think the expected output for MESSAGE_ONLY should be (1 liner)

2023-03-12 02:16:51.348 ERROR 279524 --- [nio-8080-exec-2] i.g.w.e.LoggingService                   : testing

Am I right?

Thanks!

Support ProblemDetail

Spring is supporting new way to expose errors using ProblemDetail. Please support in the starter

Extend the library to handle Graphql errors

Hello!

I think the library would grow even more if considered to include GraphQL error handling. There are a few implementations already for java-graphql and Spring framework (DGS, Kickstart, Spring GraphQL, etc.) but not many offer a simple, highly configurable error handling setup.

The main contract from which all error handlers would start is similar to the current implementation:

import graphql.GraphQLError;

public interface GraphqlExceptionHandler {

    boolean canHandle(Throwable throwable);

    GraphQLError handleError(Throwable throwable);
}

The only specific feature would be to implement a specialized bean or extend an ExceptionHandler interface required for the library to work.

Example for DGS:

@Component
public class CustomDataFetchingExceptionHandler implements DataFetcherExceptionHandler {

   @Override
   public CompletableFuture<DataFetcherExceptionHandlerResult> handleException(DataFetcherExceptionHandlerParameters handlerParameters) {
      if (handlerParameters.getException() instanceof MyException) {
         Map<String, Object> debugInfo = new HashMap<>();
         debugInfo.put("somefield", "somevalue");

         GraphQLError graphqlError = TypedGraphQLError.newInternalErrorBuilder()
                 .message("This custom thing went wrong!")
                 .debugInfo(debugInfo)
                 .path(handlerParameters.getPath()).build();

         DataFetcherExceptionHandlerResult result = DataFetcherExceptionHandlerResult.newResult()
                 .error(graphqlError)
                 .build();

         return CompletableFuture.completedFuture(result);
      } else {
         return DataFetcherExceptionHandler.super.handleException(handlerParameters);
      }
   }
}

What do you think about this?

Make `@ErrorResponseProperty` work on fields when using inheritance

I would like to define a common base exception that provides an error code for every error response in my application. This is what I've come up with:

public class ApplicationError extends RuntimeException {

  @ResponseErrorProperty("code")
  protected final String useCaseCode;

  public ApplicationError(String useCaseCode, String message) {
    super(message);
    this.useCaseCode = useCaseCode;
  }
}
public class ResourceNotFoundException extends ApplicationError {

  public ResourceNotFoundException(String useCaseCode, Class<?> resource, String resourceId) {
    super(useCaseCode, resource.getSimpleName() + " with id " + resourceId + " not found");
  }
}

Unfortunately the code field is not being serialized. Is that a known limitation of custom error fields?

UnauthorizedEntryPoint returns text instead of json

Hello,
I am trying to set up exception handling for spring security. As it says in the documentation, setting up the UnauthorizedEntryPoint:

@Bean
public UnauthorizedEntryPoint unauthorizedEntryPoint(
                                        HttpStatusMapper httpStatusMapper,
					ErrorCodeMapper errorCodeMapper,
					ErrorMessageMapper errorMessageMapper,
					ObjectMapper objectMapper) {
  return new UnauthorizedEntryPoint(httpStatusMapper, errorCodeMapper, errorMessageMapper, objectMapper);
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, UnauthorizedEntryPoint unauthorizedEntryPoint) throws Exception{

  http
            //...
            .exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint);
  
  return http.build();
}

But content type is not a json. Response:

response

add global timestamp value

As a developer, i would like to add a simple yaml or properties configuration similar to error.handling.http-status-in-json-response so that a timestamp would be added to the ApiErrorResponse object.

Usage with spring-starter-web-flux

Hey there,
we've trouble running error-handling-spring-boot-starter with spring-starter-web-flux in combination with spring-boot-starter-security.
Webflux uses ControllerMethodResolver instead of ExceptionHandlerExceptionResolver from spring-starter-web and fails to register the ControllerAdvice beans.
unfortunately we can not just add spring-starter-web, because its WebSecurityConfiguration collides with Webflux's WebFluxSecurityConfiguration.

Have you any advice, how to integrate error-handling-spring-boot-starter with spring-starter-web-flux?
Thanks in advice and keep up the great work

Support snake_case Json Response Configuration for Error Responses

My API currently uses the snake_case variable/field naming convention via Spring Boot Object Mapper, is it possible to support snake case rather than exclusively camelCase for json response field names (and their internal references to fields/properties)?

For example:
{
"code": "REQUIRED_NOT_NULL",
"message": "must not be null",
"property": "variableCamelCase",
"rejectedValue": null,
"path": "variableCamelCase"
}

Would become instead:
{
"code": "REQUIRED_NOT_NULL",
"message": "must not be null",
"property": "variable_camel_case",
"rejected_value": null,
"path": "variable_camel_case"
}

How to handle UnsupportedMediaTypeException with custom message ?

Hello @wimdeblauwe,

First of all, thanks for this amazing project ;)

I maintain an API with a PATCH endpoint with require application/merge-patch+json content-type. Since, it's not a common header I need to handle properly UnsupportedMediaTypeException. Without any custom configuration, the library returns a 415 Http Status which is great.
But, no body is returned.
Can you explain how can I customize the response body for an error which is not custom but part of the spring project.

Thanks for your help

404

The library does not handle 404 exception, isn't it?

Is there any hint how to handle 404?

Add support for javax.validation.ConstraintViolationException

The starter could add support for javax.validation.ConstraintViolationException so that the set of validation errors is added by default to the JSON response.

You get this type of exception if you do not use @Valid in the controller, but do use it on the service that the controller calls. (If you use @Valid on the controller, then you get a org.springframework.web.bind.MethodArgumentNotValidException instead, which is already handled by the library currently)

No validation error in the response when validating a @RequestParam

Hi,

I've been trying to validate a @RequestParam in a controller method, like this:

public ResponseEntity<Page<User>> getAllUsers(@RequestParam(value = "page", defaultValue = "0", required = false) @Min(value = 0, message = "Page must be positive") int page)

But when the validation fails the response only says:

{ "code": "VALIDATION_FAILED", "message": "Validation failed. Error count: 1" }

instead of showing which parameter failed and the validation error.

I've noticed that the validation error gets logged, along with other message:

i.g.w.e.ErrorHandlingControllerAdvice : getAllUsers.page: The page must be positive
h.ConstraintViolationApiExceptionHandler : Unable to convert constraint violation with element kind PARAMETER: ConstraintViolationImpl{interpolatedMessage='The page must be positive', propertyPath=getAllSimulatorConfigs.page, rootBeanClass=class com.predictor.api.controller.SimulatorConfigController, messageTemplate='The page must be positive'}

Is there something that I can do to send the error in the json response?

Project Reactor support

Is there any support for Spring Webflux (i.e. Project Reactor with Spring)?

I think it'll be super useful for a lot of people.

Allow message override for global errors

It is currently possible to override an error message using the error.handling.messages key in the application.propeties, but only for field errors, not for the global errors. This should be supported for global errors as well.

Add 401 support for when not authenticated (spring security)

Hello

Could you handle the case where the requester hasn't been authenticated?
For the moment, Spring Security return only the 403 status.

A way that could be done is by using an AuthenticationEntryPoint (reference):

@Component
public class UnauthorizedEntryPoint implements AuthenticationEntryPoint {
	
	protected final HttpStatusMapper httpStatusMapper;
	protected final ErrorCodeMapper errorCodeMapper;
	protected final ErrorMessageMapper errorMessageMapper;
	protected final ObjectMapper objectMapper;
	
	@Autowired
	public UnauthorizedEntryPoint(HttpStatusMapper httpStatusMapper, ErrorCodeMapper errorCodeMapper, ErrorMessageMapper errorMessageMapper) {
		this(httpStatusMapper, errorCodeMapper, errorMessageMapper, new ObjectMapper());
	}
	
	public UnauthorizedEntryPoint(HttpStatusMapper httpStatusMapper, ErrorCodeMapper errorCodeMapper, ErrorMessageMapper errorMessageMapper, ObjectMapper objectMapper) {
		this.httpStatusMapper = httpStatusMapper;
		this.errorCodeMapper = errorCodeMapper;
		this.errorMessageMapper = errorMessageMapper;
		this.objectMapper = objectMapper;
	}
	
	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws JsonProcessingException, IOException {
		ApiErrorResponse errorResponse = createResponse(authException);
		
		response.setStatus(errorResponse.getHttpStatus().value());
		response.getWriter().write(objectMapper.writeValueAsString(errorResponse));
	}
	
	public ApiErrorResponse createResponse(AuthenticationException exception) {
		HttpStatus httpStatus = httpStatusMapper.getHttpStatus(exception, HttpStatus.UNAUTHORIZED);
		String code = errorCodeMapper.getErrorCode(exception);
		String message = errorMessageMapper.getErrorMessage(exception);
		
		return new ApiErrorResponse(httpStatus, code, message);
	}
	
}

Though, I didn't managed to make it auto-configurable....
The only way is to use http.exceptionHandling().authenticationEntryPoint(...):

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private UnauthorizedEntryPoint unauthorizedEntryPoint;
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.httpBasic().disable();
		
		/* used for the next example */
		http.authorizeHttpRequests()
			.antMatchers("/insecure", "/secure").permitAll()
			.anyRequest().authenticated();
		
		http.exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint);
	}
	
}

And testing this method using a basic controller give the expected results:

@RestController
public class IndexController {
	
	@GetMapping("/insecure")
	public String insecure() {
		return "should be ok";
	}
	
	@PreAuthorize("authenticated")
	@GetMapping("/secure")
	public String secure() {
		return "should raise an access denied exception";
	}
	
	@GetMapping("/authenticated")
	public String authenticated() {
		return "should raise an insufficient authentication exception";
	}
	
}

What do you think?

Allow overriding of default response message

Hello,

Thank you for the efforts invested in this library! It is an awesome addition to Spring framework.

We have the situation in which we do not want to expose the internal error messages to API consumers, even if they are not explicitly caught (usually for database errors, etc.). Is there any way we can implement a functionality like in the snippet below? Any configuration I have missed for this type of behavior?

@Bean
    public ApiErrorResponseCustomizer timestampErrorResponseCustomizer() {
        return new ApiErrorResponseCustomizer() {
            @Override
            public void customize(ApiErrorResponse response) {
                // override the message property for any HTTP 500 errors
                if (response.getHttpStatus().is5xxServerError()) {
                    response.setMessage("Unknown error occurred");
                }
            }
        };
    }

Any untreated HTTP 500 errors should default to logging and a custom message. The rest of the errors should be treated as expected.

Thank you

Allow automatic conversion of Exception name to all caps code

The default current is to use the Fully Qualified Name of the Exception as the error code:

{ "code":"com.application.backend.user.UserNotFoundException"}

It would be nice if there was an automatic way to have the library generate something that is more like a code by default:

E.g. USER_NOT_FOUND

org.springframework.validation.BindException not handled

It is possible to use an object in a controller to capture the request parameters. If there is validation on that object, then Spring will throw an org.springframework.validation.BindException which is currently not handled by the library.

Example:

@RestController
    @RequestMapping
    public static class TestController {
        @GetMapping("/test/field-validation")
        public void someGetMethod(@Valid TestRequest testRequest) {

        }
    }

with TestRequest:

public class TestRequest {
        @NotNull
        private String param1;
        @NotNull
        private String param2;

       // getters and setters
    }

Because we don't handle it, a 500 status code is currently returned. It would be better to have a 400 Bad Request and a JSON similar to what we do for other validation errors.

Status Code not included in JSON

The status code is not included in the json.

I tried version 1.6.0, 1.7.0, 2.0.0. but in neither the status code '409' is included in the json response

i enabled it via property

error.handling.http-status-in-json-response=true

The Error class:

@ResponseStatus(HttpStatus.CONFLICT)
public class DuplicateException extends RuntimeException {

    @ResponseErrorProperty(includeIfNull = true)
    private final String objectName;
    @ResponseErrorProperty(includeIfNull = true)
    private final Map<String, String> identifierMap;
    private final String x = "asd";


    public DuplicateException(String objectName, Map<String, String> identifierMap) {
        super(String.format("%s already exists with parameters: %s", objectName, identifierMap));
        this.objectName = objectName;
        this.identifierMap = identifierMap;

    }
}

The Json Response:

  "code": "DUPLICATE",
  "message": "Channel already exists with parameters: {name=asd}",
  "objectName": "Channel",
  "identifierMap": {
    "name": "asd"
  }
}

Upgrade to Spring Boot 2.5 baseline

Currently, the library is compiled against Spring Boot 2.2, but this version is officially no longer supported. The current lowest version that is currently supported is Spring Boot 2.5.

Support Spring 6 and Spring Boot 3

The current version does not seem to do anything when added to a Spring Boot 3.0.0-M3 application. Will have to investigate what changed exactly and why things do not seem to be working.

Suggestions on List field validation?

Example:

@Service
class SomeService { 
   void doSomething(List<@Valid SomeItem> someItems) {}
}

Currently, ApiFieldError doesn't have a place to indicate which item within a list has the validation issue. Would it be worth adding an optional property of ApiFieldError like index to indicate the index of the problematic object in the List? I realize index may not help with Map<String, @Valid SomeItem>, for instance, or other structures. Currently we've had to reimplement ConstraintViolationApiExceptionHandler.

Thanks!

Supress Resolved warning in the logs

I put error.handling.exception-logging=NO_LOGGING in my properties file, but Resolved warning still goes in my logs. Is there any way to prevent this with some configuration?

Precedence of overrides not consistent

The precedence order of the overrides for HTTP statusses, error codes and error message is not consistent currently.

The order should be like this:

  1. If there is a property defined (using the FQN of the exception class), then use the value of that property.
  2. Next, check if there is an annotation (for HTTP status or error code). If so, use that value.
  3. Next, use a default value (500 Internal Server Error for HTTP status, using the configured DefaultErrorCodeStrategy for error codes)

RequestParams throwing MISSING_SERVLET_REQUEST_PARAMETER instead of VALIDATION_FAILED

Hi,

It wasn't very clear in the documentation whether @RequestParams would throw VALIDATION_FAILED code but I assume so, especially with the example in #20

I have a small demo

// dependencies
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.hibernate:hibernate-validator:7.0.4.Final'
implementation 'io.github.wimdeblauwe:error-handling-spring-boot-starter:2.1.0'
@Validated
@RestController
class ErrorController {
	@GetMapping("/demo")
	public ResponseEntity<Integer> demo(@RequestParam @NotEmpty String test) {
		return ResponseEntity.ok(1);
	}
}

And it throws

image

Is this the intended behavior, or did I use it wrongly?

Thanks!

error.handling.log-levels property is not being overridden

I would like to override the default values of the log-levels to

error:
  handling:
    log-levels:
      4xx: WARN
      500: ERROR

but still the exception is being logged as ERROR

2023-02-02T22:55:43.450+04:00 ERROR 9014 --- [           main] i.g.w.e.LoggingService                   : checkEmail.email: Invalid email address

I tried debugging the LoggingService and the logLevels props is empty
Screenshot 2023-02-02 at 10 59 19 PM

I have also tried adding @EnableConfigurationProperties(ErrorHandlingProperties::class) but still not working

Spring Boot v3.0.1
Java 19
Error Handling Spring Boot Starter v4.1.0

Library should be automatically used for @WebFluxTest unit tests

A test that has @WebFluxTest should need no special configuration to have the error handling library be active. In version 3.0.0, this is not the case. As a workaround, you need to add this:

@WebFluxTest
@ImportAutoConfiguration(classes ={ReactiveErrorHandlingConfiguration.class)
class MyTest {
  ...
}

Allow logging full stack trace for certain exception types

It is currently possible to set the exception logging behaviour via error.handling.exception-logging to NO_LOGGING, MESSAGE_ONLY or WITH_STACKTRACE. It might be convenient to be able to set it to NO_LOGGING or MESSAGE_ONLY, but have full stacktraces for certain exceptions like NullPointerException.

error.handling.codes doesn't overwrite

I try to wrap IllegalArgumentException with
error.handling.codes.java.lang.IllegalArgumentException=ILLEGAL_ARGUMENT as is written in documentation, but result is still tomcat error page not JSON response. My test is to put illegal simbols like 1'||( on Integer @RequestParam.

Do you have any idea how I can turn it to generic JSON respons, without trace information, like the others?

SpringBoot 2.7.6 with 3.3.0 error-handling

Support logging level based on response status

Basically when exception is throw without other exception handler, then wimdeblauwe error handler handle with put the log of error level. (Line 31, 34)

private void doStandardFallbackLogging(Throwable exception) {
switch (properties.getExceptionLogging()) {
case WITH_STACKTRACE:
LOGGER.error(exception.getMessage(), exception);
break;
case MESSAGE_ONLY:
LOGGER.error(exception.getMessage());
break;
}
}

How can I change the to another logging level?

Allow customization of JSON representation of the error

The JSON output current uses code, message, fieldErrors and globalErrors. If you want to use this library on a legacy project that already has another established naming for similar concepts, you might want to customize this to use errorCode instead of code, or description instead of message.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.